#397 Add PBKDF2,scrypt,bcrypt to the list of supported hashing functions in the 389 server
Closed None Opened 6 years ago by radegand.

Hello,

Could you please consider implementing in the 389 server a support for any of the three hashing fuctions noted above?

At the moment, one could use up to SHA512 for password hashing in the DS; however, these algorithms are still relatively fast and should the encrypted hashes were leaked, an attacker with access to modern hardware would be able to launch an effective bruteforce/dictionary attack against them.

On the other hand, PBKDF2,scrypt and bcrypt were designed to be slow (or can be easily adjusted to be slowed down) and with password storage in mind. Having password hashed via any of the above functions should slow any bruteforce/dictionary attack significantly. I'm sure there would be many users who would be really happy if they could choose any of the above algorithms for their password storage.

You can find plenty of information about this functions and their pros and cons online, for instance: http://codahale.com/how-to-safely-store-a-password/

I was told that 389 used the Mozilla NSS which seem to implement the PBKDF2 algorithm. Maybe that would be a good start? :)

Thanks in advance,
Radek Madej


One of the NSS developers did confirm that PBKDF2 is supported in NSS, so adding support for using it to hash passwords is a definite possibility.

What makes PBKDF2 slow is that it does a number of iterations of hashing. We would have to tell the NSS functions how many iterations we want to use. We would need to set the default number iterations to some recommended value (if such a value exists), but we should also make it configurable.

NSS has the ability to make a DER encoded "algorithm ID", which contains the iteration count and the salt. We would need to store this DER encoded "algorithm ID" in the userPassword value prior to the hash. This would allow us to do a hash and comparison during a bind when the stored hash uses a different count than the currently configured number of iterations. For example, the value we store would be something like this:

{PBKDF2}<algorithm ID><hash>

We would need to separate the algorithm ID from the hash when hashing a password used to bind, which would require a bit of DER parsing to read the length. We could them just pass the algorithm ID into NSS to hash the password and them do a hash comparison.

The slow hashing algorithms may be a DOS attack vector - if the hashing takes a lot of CPU time, one will need to simply start in parallel several bind requests and the server will be saturated by hash calculations. The implementation should (if possible) try to reduce the CPU priority dedicated to hash processing (or to use cgroups?)...

set default ticket origin to Community

Added initial screened field value.

Would you accept patches to add bcrypt hash support with configurable cost/work factor?

Replying to [comment:10 wclarie]:

Would you accept patches to add bcrypt hash support with configurable cost/work factor?

Yes. See http://port389.org/wiki/GIT_Rules for the rules about submitting patches. We don't have a github or gerrit style review process, we just add comments in this ticket.

I think that we should re-examine this for triage. Given current security issues in the world, we should be taking stronger measures to ensure that clients passwords are not able to be compromised if a breach were to occur.

We should also consider setting a strong password hash by default as part of this work.

Hi William,

Could it be possible to evaluate the effort needed for this implementation?

If reasonable, let's set target to 1.3.5. Otherwise, 1.3.6?

We can aim for 1.3.5 backlog and if it doesn't make it, we target 1.3.6. I don't know what would be needed for this, but happen to investigate and develop.

Replying to [comment:17 firstyear]:

We can aim for 1.3.5 backlog and if it doesn't make it, we target 1.3.6. I don't know what would be needed for this, but happen to investigate and develop.

All right. Then, let's set it to 1.3.6 for now. If you find it's doable, let's move it to 1.3.5.
Thanks!

The redefined SLAPI_LOG_ types will go away in the next patch (scrypt)

You made scrypt configurable with --enable-scrypt, but not for pbkdf2. My I ask what's the difference?

Did you happen to have a chance to build the DS with the patch [1] without --enable-scrypt?

It looks to me the scrypt related codes in pwd_init.c [2] are not in "#ifdef ENABLE_SCRYPT", which could break the build? But I could be wrong...

[1] 0001-Ticket-397-Implement-scrypt-hashing-mechanism-for-DS.patch​
[2] ldap/servers/plugins/pwdstorage/pwd_init.c

scrypt requires an external library: pbkdf2 only requires NSS, which we already depend on. This is why I decided to make this enable flag the way I did.

I did test without scrypt, but I didn't notice the missing flags. Good catch! I'll review again, and repost new patches. Thanks for your careful review.

I've pulled the pbkdf2 support, because of issues with NSS. For now, this is only adding scrypt.

Looks good, but indentation is off in pw.c.

Also, can you please not use c++/java style comments "//"?

http://www.port389.org/docs/389ds/development/coding-style.html#comments

Thanks.

Status update: The scrypt library I was using was from EPEL (opps!) not from EL7. As a result, we can't use this patch in the current form.

There are two open issues with the NSS team now:

https://bugzilla.redhat.com/show_bug.cgi?id=1371383 : Implement scrypt in NSS
https://bugzilla.redhat.com/show_bug.cgi?id=1371322 : Implement an appropriate PBKDF2 password hashing interface in NSS

Until these are satisfied, we cannot progress this ticket.

This new patch has been reviewed by someone from the NSS group, and they have approved the crypto side of it. Needs review from DS team.

Looks good. A couple of minor issues...
For the macro etiquette, better put parentheses around to avoid a problem like "size = PBKDF2_TOTAL_LENGTH * 2"?
{{{

define PBKDF2_TOTAL_LENGTH PBKDF2_ITERATIONS_LENGTH + PBKDF2_SALT_LENGTH + PBKDF2_HASH_LENGTH

35 #define PBKDF2_TOTAL_LENGTH PBKDF2_ITERATIONS_LENGTH + PBKDF2_SALT_LENGTH + PBKDF2_HASH_LENGTH
==>
35 #define PBKDF2_TOTAL_LENGTH (PBKDF2_ITERATIONS_LENGTH + PBKDF2_SALT_LENGTH + PBKDF2_HASH_LENGTH)
}}}
These are not needed?
{{{
55 #define SLAPI_LOG_ERR 0
56 #define SLAPI_LOG_PLUGIN 0
}}}
This makes me uncomfortable...
{{{
58 void
59 pbkdf2_sha256_extract(char hash_in, SECItem salt, unsigned int *iterations)
......
67 memset(iterations, 0, PBKDF2_ITERATIONS_LENGTH);
}}}
Could it be possible to change the type of iterations to PRUint32 or uint32_t?

Replacing slapi_log_error with slapi_log_err?
{{{
98 slapi_log_error(SLAPI_LOG_ERR, (char )schemeName, "Unable to retrieve symkey from NSS. Error code might be %d ???\n", status);
99 slapi_log_error(SLAPI_LOG_ERR, (char
)schemeName, "The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.\n");
}}}
Is SLAPI_LOG_PLUGIN an appropriate log level? Isn't it oo noisy?
{{{
199 slapi_log_error(SLAPI_LOG_PLUGIN, (char *)schemeName, "Comparing password\n");
}}}
This check is not needed.
{{{
143 if (enc == NULL) {
144 return NULL;
145 }
}}}
Let's not use '//' for comments... :)
{{{
266 // Future implementors of new password mechanisms may find that this function
267 // is causing them trouble. If your hash ends up as {CLEAR}{NEWMECH}.... it
268 // because NEWMECH > PWD_MAX_NAME_LEN. Update pw.h!

222 // Updated to the 13 for PBKDF2_SHA256
223 #define PWD_MAX_NAME_LEN 13
}}}

It still makes me wonder why there are this many white spaces between * and the first character. But if it is your style, I can live with it. :)
{{{
159 * This offset is to make the hash function put the values
160 * In the correct part of the memory.
}}}

commit 542287c
Writing objects: 100% (19/19), 6.74 KiB | 0 bytes/s, done.
Total 19 (delta 15), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/389/ds.git
299169e..542287c master -> master

We'll open a new ticket for SCrypt once the NSS support is there.

Metadata Update from @firstyear:
- Issue assigned to firstyear
- Issue set to the milestone: 1.3.6 backlog

2 years ago

Compiled from sources the current branch 1.3.6, 389ds generates error messages at each startup on CentOS 7.3, nss 3.28:
[root@ldap-model Admin]# rpm -qi nss
Name : nss
Version : 3.28.4
Release : 1.0.el7_3
Architecture: x86_64
Install Date: Wed 03 May 2017 09:17:56 AM CEST

error log:
...
[17/May/2017:14:53:20.046512276 +0200] - INFO - Security Initialization - slapd_ssl_init2 - Configured SSL version range: min: TLS1.0, max: TLS1.2
[17/May/2017:14:53:20.047802257 +0200] - INFO - main - 389-Directory/1.3.6.5 B2017.136.151 starting up
[17/May/2017:14:53:20.100499649 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.101782193 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.103048885 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.104325586 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.105559102 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.106792718 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.108079652 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.109299195 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.110550733 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.111855075 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.113061771 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.114308959 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.115590619 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.116814828 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.118126051 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.119353359 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.120573645 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.121826587 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.123112150 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.124333312 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.125584739 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.126865074 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.128091746 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.129343172 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.130624415 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.131847372 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.133101706 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.134400142 +0200] - ERR - PBKDF2_SHA256 - Unable to retrieve symkey from NSS. Error code might be -8190 ???
[17/May/2017:14:53:20.135611714 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.
[17/May/2017:14:53:20.136861264 +0200] - ERR - PBKDF2_SHA256 - Could not generate pbkdf2_sha256_hash!
[17/May/2017:14:53:20.159912359 +0200] - INFO - ldbm_instance_config_cachememsize_set - force a minimal value 512000
...

As a workaround i had to disable the PBKDF2_SHA256 plugin

Hey there,

This will only work on RHEL7.4, as NSS previous to that does not support PBKDF2. Sorry! You'll have to wait for 7.4 to be released. :(

[17/May/2017:14:53:20 135611714 +0200] - ERR - PBKDF2_SHA256 - The most likely cause is your system has nss 3.21 or lower. PBKDF2 requires nss 3.22 or higher.

This is why it's in the error message because I too had this exact issue :)

Sorry about that :(

Metadata Update from @firstyear:
- Custom field component reset (from Security - Password Policy)
- Issue close_status updated to: None (was: Fixed)

2 years ago

Login to comment on this ticket.

Metadata