Skip to content

Conversation

@alexdowad
Copy link
Contributor

Looking forward to hearing your comments.

@alexdowad
Copy link
Contributor Author

Failure on Appveyor looks to be spurious.

@nikic
Copy link
Member

nikic commented Jun 24, 2020

Feel free to land everything but the last commit already.

@alexdowad
Copy link
Contributor Author

Feel free to land everything but the last commit already.

I did think the last commit would be more controversial than the others. 😄

@nikic
Copy link
Member

nikic commented Jun 24, 2020

For the last commit, I have some concerns:

  • man 5 crypt lists at least two algorithms we don't support: $y$ (yescript) and $7$ (scrypt).
  • PHP has some bcrypt related weirdness, because it supports $2x$ and $2y$ prefixes. There may be some behavior discrepancy with glibc here.

@nikic
Copy link
Member

nikic commented Jun 24, 2020

So, now I'm left wondering what actually happens if we use the glibc implementation, wrt to $2y$.

My current state is that we probably never use the glibc implementation, because $php_crypt_r gets set to 0, because the function is checked in the wrong library (and later in the correct library).

@nikic
Copy link
Member

nikic commented Jun 24, 2020

I've applied 7d05bc8 to fix the crypt_r detection, and instead added a || true to the code picking the implementation, so it's a bit more honest about what's going on :)

@nikic
Copy link
Member

nikic commented Jun 24, 2020

I've also fixed one behavior difference in 4c4af2b (landed this one in 7.4).

There's a diff in ext/standard/tests/strings/crypt_sha256.phpt:

Iteration 8 failed.
Expected: <$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL972bIC>
Got       <*0>
Passes.

It looks like we aren't rejecting overly low rounds.

@nikic
Copy link
Member

nikic commented Jun 24, 2020

I've addressed that discrepancy with 8a8c8d4.

@nikic
Copy link
Member

nikic commented Jun 24, 2020

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

@alexdowad
Copy link
Contributor Author

For the last commit, I have some concerns:

  • man 5 crypt lists at least two algorithms we don't support: $y$ (yescript) and $7$ (scrypt).
  • PHP has some bcrypt related weirdness, because it supports $2x$ and $2y$ prefixes. There may be some behavior discrepancy with glibc here.

...

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.

Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.

It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.

If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

PHP contains a (presumably) correct, portable, and efficient implementation of
`crypt_r` hashing, including all the possible hash algorithms which libc's
`crypt_r` may possibly implement.

Since this is so, why should we test for the platform `crypt_r` and only use
our own implementation if it's not there? What benefit could there be from
using libc's `crypt_r`? Maybe it might be faster? If so, PHP's implementation
can be optimized. There is nothing "magic" which libc can do and which PHP
can't do.

If we didn't have a full implementation, it would make sense to take advantage
of the one in libc, but since we do, this is just complicating things.
@alexdowad
Copy link
Contributor Author

By the way, @nikic, thanks for finding those other problems with PHP's crypt_r. 👍

@nikic
Copy link
Member

nikic commented Jun 24, 2020

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.

Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.

It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.

If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

We already have a high-level portable API for password hashing, which is the password_hash_* family of functions. You shouldn't be messing with tricky crypt() API if a portable password hash is all you want.

Using crypt() nowadays only ever makes sense if you specifically need to interoperate with crypt() based systems, e.g. if you want to process passwd files from PHP. For such use-cases, the only thing you care about is that crypt() in PHP behaves consistently with other crypt() based APIs on the same system.

@alexdowad
Copy link
Contributor Author

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.
Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.
It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.
If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

We already have a high-level portable API for password hashing, which is the password_hash_* family of functions. You shouldn't be messing with tricky crypt() API if a portable password hash is all you want.

Using crypt() nowadays only ever makes sense if you specifically need to interoperate with crypt() based systems, e.g. if you want to process passwd files from PHP. For such use-cases, the only thing you care about is that crypt() in PHP behaves consistently with other crypt() based APIs on the same system.

OK. Fair enough.

If that is so, it does call into question why we have the in-tree implementation of crypt_r and its various hashes. It sounds like it is basically just for people who are misusing the crypt() function.

@alexdowad
Copy link
Contributor Author

@nikic... So I guess I can close this PR?

Do you think the docs for crypt should be updated to reflect its intended use?

@nikic
Copy link
Member

nikic commented Jun 24, 2020

Just my 2c ;) Maybe, given that we have not been using system crypt for so long due to a configure bug, it makes more sense to drop support for it as proposed.

I wonder if @remicollet or @oerdnj patch PHP to use system crypt or not. (Distros commonly disable any custom implementations we have :)

@nikic nikic changed the title More simplification and cleanup of cryptographic hashing code Always use PHP's own crypt_r implementation, don't support system crypt Jun 24, 2020
@oerdnj
Copy link
Contributor

oerdnj commented Jun 25, 2020

Here's the commit from packaging repo:

commit ff02f63e0687d2325b89c51da883c5af005d1068
Author: Ondřej Surý <[email protected]>
Date:   Fri Nov 16 15:17:55 2012 +0100

    Return to PHP versions of crypt() functions, it's to big burden to carry on the patch

@alexdowad
Copy link
Contributor Author

Here's the commit from packaging repo:

commit ff02f63e0687d2325b89c51da883c5af005d1068
Author: Ondřej Surý <[email protected]>
Date:   Fri Nov 16 15:17:55 2012 +0100

    Return to PHP versions of crypt() functions, it's to big burden to carry on the patch

Thank you! Which repo is this?

@alexdowad alexdowad requested a review from bukka as a code owner October 7, 2023 13:51
@alexdowad
Copy link
Contributor Author

Closing due to inactivity.

@alexdowad alexdowad closed this Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants