Scott Arciszewski <sc...@paragonie.com> schrieb am So., 5. Juni 2016 10:13:
> On Sat, Jun 4, 2016 at 6:15 PM, Stanislav Malyshev <smalys...@gmail.com> > wrote: > > > > Hi! > > > > > Let's begin discussing the prospect of adding libsodium as a core > extension > > > in PHP 7.1. I've updated the RFC to explain why this would be a good > idea > > > and the benefits it offers. > > > > > > https://wiki.php.net/rfc/libsodium > > > > > > If the subsequent discussion goes smoothly, I would like to open > voting on > > > June 15. > > > > Some notes based on the docs in > https://paragonie.com/book/pecl-libsodium: > > TLDR: I think the idea of having something like this in core is very > > nice, but I think it needs some tweaks in order to be a solution we can > > recommend as core module. > > > > - I would appreciate deeper namespacing. It is rarely that you would use > > all sub-modules (such as encryption, both symmetric and asymmetric, > > password hashing, decryption, random, etc.) in the same piece of code. > > So if I could just "use Sodium\Crypto;" and then use short names it > > would be much nicer than having to spell out the whole story. > > This would entail a BC break against all software currently written > using libsodium. > Are you certain that deeper namespacing would be worth that trade-off? > > > - Also, I'm not sure why functions like > > crypto_aead_chacha20poly1305_encrypt() exist. Shouldn't algorythm be a > > parameter to encryption function and not function name? Putting > > parameter into function names makes it much harder to be flexible and > > configurable. Or, if there's only one, then why not just call it > > encrypt() and state the fixed algorithm in the docs? > > Libsodium offers few primitives. For AEAD, you have: > > - ChaCha20-Poly1305 > - AES-256-GCM (but only with modern hardware) > - ChaCha20-Poly1305 (IETF version with a bigger nonce) > > These are distinct functions in the C API to discourage "Hey, I'll add > another algorithm and users can access it by changing the string > that's passed". > > When all is said and done, crypto_aead_encrypt() and > crypto_aead_decrypt() will be the CAESAR winner. > https://competitions.cr.yp.to/caesar.html > > > - The function names in general are kind of all over the place. I.e., to > > get a random, you get: > > - for string: _buf > > - for ranged (I assume unsigned?) integer: _uniform > > - for 16-bit unsigned integer: _random16 > > If you can notice a pattern here, I can't. Also, I don't see why you > > have a function for 16-bit int but not for 8-bit or 32-bit. Additionally > > weird that _uniform gets int, but has limit different from PHP int. > > To be honest, most of these aren't necessary in PHP anymore. They were > mostly useful in PHP 5.x before we had random_bytes() and > random_int(). > > > - Naming/namespacing of constant-time function should make it clear they > > are there because they are constant time, not just because somebody > > wanted to reimplement bin2hex. It's also unclear why we need memcmp as > > separate function from hash_equals(). > > Alternatively, if we can make bin2hex() and hex2bin() always > constant-time in PHP, we can eschew exposing these libsodium > functions. (Just make an alias for BC purposes.) I'd actually prefer > that. > Can't we have the aliases in userland for BC? I don't see a reason to introduce aliases that are automatically deprecated. Same for all other functions. If they're namespaced, a wrapper can be created for BC. And we can have nice names in PHP. > Also, I'm still not convinced bin2hex in PHP even has a timing problem. > > I haven't seen anything but vague generic theoretising in this regard. > > Same with hex2bin (in fact, even more since hex2bin doesn't even have > > index lookups). > > These are the facts: > > 1. Index lookups based on the contents cryptographic secrets is a > recipe for microarchitecture side-channels (e.g. FLUSH+RELOAD). > 2. The current implementation of all RFC 4648 encoding functions that > PHP has (which, strangely, doesn't include base32) violates rule 1. > > > https://cryptocoding.net/index.php/Coding_rules#Avoid_table_look-ups_indexed_by_secret_data > > See how Halite stores keys for an example of "Yes, this does get used > for crypto secrets": > > https://github.com/paragonie/halite/blob/6c026f7dc6a57ecd6c65e5944057acdefa8c9d67/src/KeyFactory.php#L604-L627 > > > - What exactly memzero does in PHP? Looks like it accepts argument > > by-ref, which means if you do something like: > > It overwrites every byte in a string with NUL characters. > > > function foo($secret_key) { > > // do stuff with key > > memzero($secret_key); > > } > > > > and then: > > > > $key = get_key(); foo($key); > > > > then $key still has the key. So I'm not sure how that all memory wiping > > is still working in practice. I mean, it may work with random keys that > > you generate, use once and immediately destroy, but in any other > > scenario it's just wasting time. Even with random keys it's iffy since > > it assumes your RNG state is either not in memory or is protected. > > Right, it has to be used with care. But the existence of a > well-written cross-platform memory-zeroing function is almost reason > enough to vote in favor of libsodium. > > See also: https://stackoverflow.com/a/29331937/2224584 > > > E.g. in the example at > > > https://paragonie.com/book/pecl-libsodium/read/09-recipes.md#encrypted-cookies > > keys are meticulously erased, but since they are all deterministically > > derived from $this->key (and cookie name which is public) which stays in > > memory, what exactly is the point? > > That's a good question: > > http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html > > > - increment() needs clearer explanation what it does (e.g. does it > > accept any string? What exactly does it do to that string?) and also it > > seems to be it would be nicer to just return the value. Or at least have > > this option - mutation in place is not always what you want. > > It's used for incrementing a nonce for, e.g. CTR mode. In little-endian. > > That's a design issue that should be relatively non-controversial if > you want to raise it: > https://github.com/jedisct1/libsodium-php > > > - Why version functions are functions and not constants? > > > > - Names like "secretbox" are weird to me - what exactly is "secretbox" - > > is it encryption? Decryption? hashing? Is it symmetric or asymmetric? It > > would be nicer to use established and more clear terminology. Same with > > other names - e.g. crypto_auth - what it does? Does it check the message > > for authenticity or generates the signature for somebody else to check? > > Turns out the latter, but it's not clear from the name. > > See http://nacl.cr.yp.to > > > - Same with crypto_box() - actually it differs from crypto_secretbox() > > by... try to guess what. You would never guess. The former is > > asymmetric, the latter is symmetric. > > The origins are academic. All you need to know is: > > - crypto_box means public key encryption > - crypto_secretbox means secret key encryption > > > - It's not clear why keypair parameter is string - if it's two keys, how > > it is one string? Also, why you need a keypair to encrypt-decrypt if > > you'd use only one key in each case (public or private)? What you do if > > you only have public key - how would you decrypt a message? Can you > > decrypt a message at all if you don't have secret key - and if so, how? > > > > - crypto_box_keypair_from_secretkey_and_publickey seems to use secret > > and public key from different people, so the result is not what is > > usually called a key pair (set of public+private keys belonging to one > > user) - in fact, I don't know what the result is. Could you explain? > > A keypair is used in some APIs (crypto_box_seal_open comes to mind). > All that function does is concatenate the two. > > It has nothing to do with key exchange. > > > - After looking into crypto_sign_open I understands that it separates > > the message from attached signature and verifies the signature. But it's > > a bit confusing as it doesn't actually open anything. > > crypto_sign doesn't do detached signatures. You take a signed message > and a public key and, if the signature is good, you got the unsigned > message. > > I personally prefer crypto_sign_detached for that reason. > > > - It is unclear why you need different functions to generate encryption > > keypair and signing keypair. > > Different algorithms. One is Elliptic Curve Diffie Hellman, the other > is DSA over an Edwards Curve. You can transform keys from one to the > other, but using one in both places without conversion is something I > would encourage great caution. > > > - The API never seems to either document or allow any choice of the > > algorithms. > > Yes, as mentioned above, that is INTENTIONAL. > > Libsodium is an opinionated cryptography library that doesn't give you > a lot of levers to pull -- only secure defaults you can't change, > consisting of carefully-selected cryptography primitives. > > > While it can be a boon for simplicity, I do not see how such > > code could be made to interoperate with code in other languages and > > other systems. > > That isn't its purpose. Its purpose is to be secure. (It also happens > to also be extremely fast.) > > > I mean, I can generate the signature easily, but how > > would I check such signature in, say, Python or Java? > > By using Libsodium. There are bindings for most popular programming > languages already. > > > The docs give no clue. It's OK to support only one algorithm if it's > > considered superior (though what the users would do if it turns out > > not to be the case?) but at least it should be thoroughly documented. > > > https://download.libsodium.org/libsodium/content/public-key_cryptography/authenticated_encryption.html#algorithm-details > > > - If crypto_pwhash_str highly recommends using provided constants, why > > not make these parameters optional with defaults being recommended > > constants? > > > > - crypto_pwhash_scryptsalsa208sha256 looks awfully specific (and long). > > Is that the only algorithm supported? If yes, do we need to spell it out > > in the name (and not the docs)? If not, why it's not a parameter? > > That's the long-form of "scrypt". Personally, I'd say exclude it and > just use crypto_pwhash (Argon2i). No disrespect to Colin Percival. > > > - Is there any support for importing/exporting keys in any of the > > established formats? Is the library inter-operable with any of the > > existing key/data interchange formats? > > Keys are raw binary strings, unless you use a high level function. > > > - Function names like crypto_sign_ed25519_sk_to_curve25519 seem to not > > be very usable to common people. The docs says "Transform crypto_sign > > key into crypto_box key" - maybe the name should reflect it? > > These are auxiliary functions, not mainline functions. Most PHP > developers will only be using: > > * crypto_box > * crypto_secretbox > * crypto_sign > * crypto_auth > * crypto_generichash > * crypto_pwhash > > > Names like crypto_stream_xor have a similar problem - what it does is > > encrypts stream with a key, according to docs. Looks like it uses XOR > > for it, but is it the most important part for the user or the fact it > > encrypts? Maybe it should be crypto_stream_encrypt or something? Also, > > does it really do just XOR? Because XOR is not really the best idea to > > do even if you don't care about authenticity - due to trivial chosen > > plaintext attack. Probably it does more than mere XOR, but then I'm not > > sure what exactly. > > This is how a stream cipher works: > > 1. You take your key and nonce, and generate a long string of random > bytes deterministically from your key and nonce. > 2. To encrypt: You XOR every byte of plaintext with a corresponding > byte of the keystream. > 3. To decrypt: You XOR every byte of _ciphertext_ with a corresponding > byte of the keystream. > > This is unauthenticated encryption; don't use it unless you're > building something with it and authenticate elsewhere. > > > - Why one would use crypto_scalarmult? That looks like a random piece of > > low level API without clear indication why it exists. > > It's used to derive a shared secret from an X25519 secret key and an > X25519 public key. > > > - What is the difference between crypto_stream and randombytes_buf? Both > > seem to produce a random string of given length. I assume crypto_stream > > does more but the docs do not explain. > > crypto_stream is deterministic; randombytes_buf is non-deterministic > > > - For crypto_kx, it is not clear what exactly this function does and why > > the same parameter is passed twice in different places. I mean, if you > > know the details of how DH key exchange works, it may make sense, but if > > we want to make it simple for the common user, it needs some better > > explanations and maybe better parameters. > > This is basically a multi-step crypto_scalarmult in one complete pacakge. > > > - Names like CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE > > look very painful. Yes, people have IDEs and copy-paste, but imaging to > > have to type it just once over ssh connection in vim, where copy-paste > > is not working. Can't we have something more concise and put the rest in > > the docs? > > That's a point worth considering. (Alternatively: Eschew scrypt.) > > > This came out longer than I expected (hopefully somebody made this far?) > > and more disorganised, so I provide a quick summary: > > - Need better naming, both namespaces and functions > > - Need better docs explaining what the functions do and why > > The docs are currently my responsibility; I apologize for not putting > more time into them. > > > The stated goal is "You shouldn't need a Ph.D in Applied Cryptography to > > build a secure web application." I fully agree with this goal. I however > > feel that current implementation, while making admirable progress > > towards this goal, still needs some work to actually achieve it. > > > > -- > > Stas Malyshev > > smalys...@gmail.com > > I hope I've addressed your important questions adequately. > > Scott Arciszewski > Chief Development Officer > Paragon Initiative Enterprises <https://paragonie.com> > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >