看板FB_security
标 题Better Password Hashes
发信站Nanoman's Company (Sun Jul 7 21:36:22 2013)
转信站ptt!csnews.cs.nctu!news.cs.nctu!.cs.nctucs.nctu!!freebsdfreebsd.org!ow
--dc+cDN39EJAMEtIO
Content-Type: multipart/mixed; boundary="n8g4imXOkfNTN/H1"
Content-Disposition: inline
--n8g4imXOkfNTN/H1
Content-Type: text/plain; charset=iso-8859-1; format=flowed
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
My friend and fellow FreeBSD enthusiast Derek Marcotte recently pointed out=
that FreeBSD has no easy way to set the logarithmic rounds for bcrypt pass=
word hashes. Doing so is trivial in OpenBSD, and considering the capabilit=
ies of current GPU attacks, I want this functionality.
This issue was raised over eight years ago in kern/75934 by Steven Alexande=
r Jr., who included a patch to add this feature. Unfortunately, this seems=
to have been completely overlooked, and there were no public responses to =
this PR.
I commissioned Derek to come up with a solution by either updating Steven's=
patch or by devising a new method. To paraphrase Derek's comments:
-----BEGIN PARAPHRASIS-----
I did some research into what other *BSDs are doing. OpenBSD and NetBSD us=
e the algorithm name, a comma, and then the number of rounds:
http://www.openbsd.org/cgi-bin/man.cgi?query=3Dlogin.conf&sektion=3D5
localcipher=3Dblowfish,6
http://netbsd.gw.com/cgi-bin/man-cgi?passwd.conf+5+NetBSD-current
localcipher=3Dblowfish,6
To me, this isn't a good way to do it because we'd need special rules to pa=
rse this extra field out of the previously unstructured data. This parsing=
would be algorithm dependant.
Everyone knows about modular crypt, so why not feed the modular crypt salt =
string as the parameter directly? Instead of messing with different names,=
give the power to the system admin to control this directly, so when crypt=
is updated, pam_unix can take advantage. Each implementation of crypt alg=
orithms already includes parsing of the salt magic.
I found that patching pam_unix was the least invasive way to handle configu=
rable hashes for login. I've added a passwd_modular parameter that will su=
persede passwd_format when defined. passwd_modular will feed directly into=
crypt, so any options that are passed to crypt via the salt are immediatel=
y available for use in the master.passwd file. For example:
:passwd_modular=3D$2a$11$:\
Now you can also set the rounds for sha512:
:passwd_modular=3D$6$rounds=3D1000000$:\
To disable passwd_modular and revert to passwd_format:
:passwd_modular=3Ddisabled:\
This also lets admins shoot themselves in the foot by supplying invalid or =
bad salts. For example:
:passwd_modular=3D$1$constantsalt:\
I had considered setting a second variable like ":passwd_param=3D8:\", but =
then you really have to mess with crypt to make it work. I think it would =
be a much more invasive change, and unnecessary, providing the documentatio=
n for login.conf is brought up to date.
FreeBSD 8.* doesn't have access to the SHA family of hashes. If this is me=
rged back into 8, it will give much stronger password security when using $=
2a$08$ (or higher) than is currently available.
bcrypt is preferable to sha512 because of its resilience to current GPU att=
acks. This is expected to change. Hopefully, my patch will lay some groun=
dwork to incorporate scrypt.
-----END PARAPHRASIS-----
I've attached a copy of Derek's patches for the FreeBSD 9-STABLE versions o=
f pam_unix and the login.conf man page. These may have to be adjusted for =
HEAD.
I really like Derek's solution. It's working perfectly for bcrypt on my ow=
n network, and I'm planning to distribute it to the hundreds of FreeBSD ser=
vers that I am responsible for maintaining. In my opinion, committing Dere=
k's patches will allow kern/75934 to be closed.
--=20
A.J. Kehoe IV (Nanoman) | /"\ ASCII Ribbon Campaign
Nanoman's Company | \ / - No HTML/RTF in E-mail
E-mail:
[email protected] | X - No proprietary attachments
WWW:
http://www.nanoman.ca/ | / \ - Respect for open standards
--n8g4imXOkfNTN/H1
Content-Type: text/x-diff; charset=iso-8859-1
Content-Disposition: attachment; filename="pam_unix.c.patch"
Content-Transfer-Encoding: quoted-printable
--- /usr/src/lib/libpam/modules/pam_unix/pam_unix.c.orig 2013-07-07 10:20:4=
6.000000000 -0400
+++ /usr/src/lib/libpam/modules/pam_unix/pam_unix.c 2013-07-07 12:53:28.000=
000000 -0400
@@ -68,8 +68,9 @@
#include <security/pam_mod_misc.h>
=20
#define PASSWORD_HASH "md5"
+#define NOMODULAR "disabled"
#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
-#define SALTSIZE 32
+#define SALTSIZE 64
=20
#define LOCKED_PREFIX "*LOCKED*"
#define LOCKED_PREFIX_LEN (sizeof(LOCKED_PREFIX) - 1)
@@ -77,6 +78,7 @@
static void makesalt(char []);
=20
static char password_hash[] =3D PASSWORD_HASH;
+static char password_nomodular[] =3D NOMODULAR;
=20
#define PAM_OPT_LOCAL_PASS "local_pass"
#define PAM_OPT_NIS_PASS "nis_pass"
@@ -272,7 +274,7 @@
char salt[SALTSIZE + 1];
login_cap_t *lc;
struct passwd *pwd, *old_pwd;
- const char *user, *old_pass, *new_pass;
+ const char *user, *old_pass, *new_pass, *modular_salt;
char *encrypted;
time_t passwordtime;
int pfd, tfd, retval;
@@ -378,16 +380,23 @@
return (PAM_BUF_ERR);
=20
lc =3D login_getclass(pwd->pw_class);
- if (login_setcryptfmt(lc, password_hash, NULL) =3D=3D NULL)
- openpam_log(PAM_LOG_ERROR,
- "can't set password cipher, relying on default");
- =09
+
+ memset(salt, 0, sizeof(salt));
+ modular_salt =3D login_getcapstr(lc, "passwd_modular", password_nomodula=
r, NULL);
+ if (strcmp(modular_salt, password_nomodular) =3D=3D 0) {
+ if (login_setcryptfmt(lc, password_hash, NULL) =3D=3D NULL)
+ openpam_log(PAM_LOG_ERROR,
+ "can't set password cipher, relying on default");
+ } else {
+ strncpy(salt, modular_salt, sizeof(salt) - 1);
+ }
+
/* set password expiry date */
pwd->pw_change =3D 0;
passwordtime =3D login_getcaptime(lc, "passwordtime", 0, 0);
if (passwordtime > 0)
pwd->pw_change =3D time(NULL) + passwordtime;
- =09
+
login_close(lc);
makesalt(salt);
pwd->pw_passwd =3D crypt(new_pass, salt);
@@ -464,13 +473,25 @@
makesalt(char salt[SALTSIZE])
{
int i;
+ int remainder;
+
+ /* If a salt magic has already been set, skip to the free area */
+ for (i =3D 0; i < SALTSIZE; i++) {
+ if (salt[i] =3D=3D '\0') {
+ break;
+ }
+ }
=20
/* These are not really random numbers, they are just
* numbers that change to thwart construction of a
* dictionary. This is exposed to the public.
*/
- for (i =3D 0; i < SALTSIZE; i +=3D 4)
- to64(&salt[i], arc4random(), 4);
+ while (i < SALTSIZE) {
+ remainder =3D SALTSIZE - i;
+ to64(&salt[i], arc4random(), (remainder < 4 ? remainder : 4) );
+ i +=3D 4;
+ }
+
salt[SALTSIZE] =3D '\0';
}
=20
--n8g4imXOkfNTN/H1
Content-Type: text/x-diff; charset=iso-8859-1
Content-Disposition: attachment; filename="login.conf.5.patch"
Content-Transfer-Encoding: quoted-printable
--- /usr/src/lib/libutil/login.conf.5.orig 2013-07-04 10:16:42.000000000 -0=
400
+++ /usr/src/lib/libutil/login.conf.5 2013-07-04 10:31:59.000000000 -0400
@@ -275,6 +275,14 @@
NIS clients using a
.No non- Ns Fx
NIS server should probably use "des".
+.It "passwd_modular string $02$08$ The encryption format that new or"
+changed passwords will use, based on the=20
+.Xr crypt 3=20
+magic constants. Overrides passwd_format when set. Valid values include "=
disabled" to fall back to passwd_format, $02$08$ would be blf with work fac=
tor 8, or $6$rounds=3D5000$ would be sha512 with 5000 rounds, will accept a=
ny of the magic salt values from
+.Xr crypt 3
+Be aware that setting this to an invalid crypt magic will likely fall back=
to des. Appending text to after the salt magic, (e.g. $02$08$dontdothis) w=
ill weaken the salt. Please refer to
+.Xr crypt 3
+for proper syntax and useage.
.It "passwd_prompt string The password prompt presented by
.Xr login 1
.It "times.allow list List of time periods during which
--n8g4imXOkfNTN/H1--
--dc+cDN39EJAMEtIO
Content-Type: application/x-pkcs7-signature
Content-Disposition: attachment; filename="smime.p7s"
Content-Transfer-Encoding: base64
MIIPUAYJKoZIhvcNAQcCoIIPQTCCDz0CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
DLwwggV3MIIDX6ADAgECAgMM9zQwDQYJKoZIhvcNAQEFBQAweTEQMA4GA1UEChMHUm9vdCBD
QTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNp
Z25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcwHhcN
MTMwMzExMjMyMzI2WhcNMTMwOTA3MjMyMzI2WjA9MRgwFgYDVQQDEw9DQWNlcnQgV29UIFVz
ZXIxITAfBgkqhkiG9w0BCQEWEm5hbm9tYW5AbmFub21hbi5jYTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAK9WRGqRDUDjWwNIfZTBp4FL5bI0kY3ZqvM6tEO+Sqp5YxATre8F
a+BYbeNp/8MKfuPrRgE2jRzlePAx7kpvZUhRTGAZpncmHC7Z3FDl8Ugid4193ReCfPypb9Gs
3ZgPfzJyNuDeCM3amz/cDXC/makJLpmLzu95D91hD+V30iActE5j1tNewMq9qJRoEdr5Tqus
bUjjDm8kiK5sz9JzQjFoufuaWIR57w2Sm1gDVZ0MH46fxZ/SwLDDzt4VC2u+1oS4KSmVUm6X
Wv1/Fmdf2sOOu9Ro2xVjJHW+j16lsFPPj+lkDv5tb0G7I2vBoKEQg/s+h8J4F+l/xPL3O5xB
c68CAwEAAaOCAUIwggE+MAwGA1UdEwEB/wQCMAAwVgYJYIZIAYb4QgENBEkWR1RvIGdldCB5
b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSBoZWFkIG92ZXIgdG8gaHR0cDovL3d3dy5D
QWNlcnQub3JnMA4GA1UdDwEB/wQEAwIDqDBABgNVHSUEOTA3BggrBgEFBQcDBAYIKwYBBQUH
AwIGCisGAQQBgjcKAwQGCisGAQQBgjcKAwMGCWCGSAGG+EIEATAyBggrBgEFBQcBAQQmMCQw
IgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLmNhY2VydC5vcmcwMQYDVR0fBCowKDAmoCSgIoYg
aHR0cDovL2NybC5jYWNlcnQub3JnL3Jldm9rZS5jcmwwHQYDVR0RBBYwFIESbmFub21hbkBu
YW5vbWFuLmNhMA0GCSqGSIb3DQEBBQUAA4ICAQCnV4v+VWIuG3iB7apL1Ht4m86rttYwtG/r
JTuacyE7NB2nhK5/MIj3+bVy73g9hxco7FF+L+wMvEm7J19Z6f97p7LlfN0JASWEEDpnzzyZ
RCHktiO7IYWGNWGEhR1WDJfalqupo33x0Z7vs51koZuxW1yJV+ZQTzBIJRKWcENA3r2pVhRm
L32yzw0qx+JXGSimcpKRv45xl2bPQjF0vEFr69ur74YDQc9k0DH/ZWzbOayq3PDzrRBzQTZ5
8rS95EqFNAR3lNDZ9OABCD/L6XcJB5KIntY3DrL9p1zni9NhWPkcXYDY9xfyfI4dMbQUD/WY
tgn13Ihu5QUgNZ9VePIAKbtJZBsptEoKSHnQx2upcEYmyEIaH8lm6iOsC6uBfCSjYyp3W1BK
eW95/pRkMWWBt65WEe55sxEEMM40SBT4+ycjvw1UWB2R4aRdgDlLLZK5/uvBP0mVzYO0Mi3g
E8UD+tNKEhlo8H9t8AXLrij1mStSFsF3C76DN5YuBFaKr4odQHaJskyz9oxAX0nwqwJbjoYI
Z3RhxNXd1DK1hIEWclEqdnuRSICEqqI3htG85SyVr62OZJg2zml2swhZLg2Q9yrCnZGCy46N
lLAzoV3tEG9Oh4MTsa+1hzJeNLXnvUWE5jHku9SeClmDM6J0Bp9FnsSnDNlUEYYL443qFBz7
zzCCBz0wggUloAMCAQICAQAwDQYJKoZIhvcNAQEEBQAweTEQMA4GA1UEChMHUm9vdCBDQTEe
MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p
bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcwHhcNMDMw
MzMwMTIyOTQ5WhcNMzMwMzI5MTIyOTQ5WjB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQL
ExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmluZyBBdXRo
b3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZzCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAM4iwOJGfew2KAdQlvKgM0CMS/E7Zj8x5WsCNtvWfPbxiI9O
dzYFQZX5CfASz0aGc2C3bn7owFhkrs2wrUUXDGP6Zwro1tK/PueYxPBM+uADuzVdbCHeniDZ
us1mMjdy+vcI9cfNWMmO5w5e6j7+HKEUChVshoRbZGYqeqlLU3n1iKJ77i8KYSuNsn5NVqUT
7Orakp6sREEeWGBlBWb4wES9y5T3Qn4L92VomFEF8PMFkQQdGxeC7MhXu8NreojxsHLMJVsg
kewWAhKPMukXGEjQxwUuAjBCuCWcBWs/qjqn61NI9+jStgeY3BvGNH9/yRyCegVYKwhb8zii
qxddZsmY154Qi6LS3XSa93EMcmDfzW+YM52WNHY+JHqSsA6VHm/moEU4R6rXQe1KtxL21xuD
ig8u2Am2WdeqBP/Sk31oLt2LS6tYui+N6pWnoMNUiaX724tRIp2yw74RviyRhouWeK0g04ov
Gj/G0FFlhyGxGQFlf0Uch/V80EFMTymYIf0zH3UMBFH6GXfb1BQc7oHDHfWYt2kGkSLdAFDM
gTGsEgd7ONpoW+Yr1H7JX63o63JM8wHlSyC/mqZXypEAAYuhdSE3tWMNZz5GT3AgZ87F1lnb
AuDw0svNumK3kEHo3SDkKbxkKULIItx4mv9D7JgbCVFLWlrCcfHEy3Op5aELAgMBAAGjggHO
MIIByjAdBgNVHQ4EFgQUFrUyG9TH8+DmjvO90rA67rI5GNEwgaMGA1UdIwSBmzCBmIAUFrUy
G9TH8+DmjvO90rA67rI5GNGhfaR7MHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0
dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0
eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnggEAMA8GA1UdEwEB/wQFMAMB
Af8wMgYDVR0fBCswKTAnoCWgI4YhaHR0cHM6Ly93d3cuY2FjZXJ0Lm9yZy9yZXZva2UuY3Js
MDAGCWCGSAGG+EIBBAQjFiFodHRwczovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwNAYJ
YIZIAYb4QgEIBCcWJWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZy9pbmRleC5waHA/aWQ9MTAwVgYJ
YIZIAYb4QgENBEkWR1RvIGdldCB5b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSBoZWFk
IG92ZXIgdG8gaHR0cDovL3d3dy5jYWNlcnQub3JnMA0GCSqGSIb3DQEBBAUAA4ICAQAox+6c
ggK6XIASyjUKHYFviWqZzPJoD3+n4Y1YlT698gbDkFqstWD2mUMBo4hwnJ1inaSHr2dYDTA2
O+atSNPLdAKGcT7iKwNo8TRiQEY7U+oo9Kz7ZpVTik1d/TvZYNfKeWk7sWWSpsaBglyczetN
AYql3xFVqhXKHzfAgphwYdtqfJajji5UPk8hqZDv3IK/3OhFrU2Qcwg8lGWwBJl2f+K8wmoV
qpcENyTYHpRObQ5RvtbEj8qWbfdD3+gwZSc7e7tDQ2PEQ/ey7GjM4RmOIvuY4XtaPgE3O4sI
sKLzlU4ay5vNmrHbsnDwLUrb2LDjb0VIMxL//jwyKlT3xPeK8Igjwkf+ZHpxwNEepmOwB36k
L9MBj9yfK7bGCKkPk0gl/BL9n0Lc88Q+9lew191p0QZ3NApL0sqg/xzGjMkWvsTMMjdoc18I
+1H3SVM2BQqVAkzyeRoQ9tg6dZzzHfGiDXBnhhuzFvUv5aTreYb5PQvCcwulmaxv/Ge45S8L
phgkjXvRSDUpGECsk2DhloZQtHpZ2I8hC5/PgpHGO79r3AeRuZdWI6q2bJTGSAY85M5OquT2
LwncU28u/HTrOmOZwqasibynskSgDYoQ42zyJMv6m59wRy7eFIvUsiAJlqJk8SQc3KE1nBWy
1LxVLn0G9ZwOVfRa1pPadq0lc0zFQzGCAlwwggJYAgEBMIGAMHkxEDAOBgNVBAoTB1Jvb3Qg
Q0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBT
aWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnAgMM
9zQwCQYFKw4DAhoFAKCBsTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
BTEPFw0xMzA3MDcxNzM2MjJaMCMGCSqGSIb3DQEJBDEWBBR0mKxlfZbMuxrxKXqfXBRnyBgB
SjBSBgkqhkiG9w0BCQ8xRTBDMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG
9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkqhkiG9w0BAQEFAASCAQAbiqNA
WEXKX7girXm3MT5pp98eEe5GMEMWfaIRtJWvpTLPkkAghBwyWcU2+2Z4vxUUJOABNnJmJznD
zrv4DQwaZ2DcmdArhvgyq28drWeB7qL1hsPACKm1MZ2HD53ZKBwl0GiMR8IVqC4G6AtDwIhb
NAY6HJu98Xrg4zZaKIoRr66AWq95fQgOKButaf3AuZ3tfI8Bnht8MbnlicDCkc8Hn8DPdOT1
B3+k0r3q1qWtMPifo3wkSQKzS0RxXauz6owDYGrg252mgWWz2/B2hVGfl27HWva7lvFHComL
iVwNK39jwZ11C2dGd0CFQVkry/M9eEX6+CHp4akZjxkyo/Al
--dc+cDN39EJAMEtIO--