| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,348 @@ |
| 1 |
+# Sodium Compat |
|
| 2 |
+ |
|
| 3 |
+[](https://github.com/paragonie/sodium_compat/actions) |
|
| 4 |
+[](https://github.com/paragonie/sodium_compat/actions) |
|
| 5 |
+[](https://ci.appveyor.com/project/paragonie-scott/sodium-compat) |
|
| 6 |
+[](https://packagist.org/packages/paragonie/sodium_compat) |
|
| 7 |
+[](https://packagist.org/packages/paragonie/sodium_compat) |
|
| 8 |
+[](https://packagist.org/packages/paragonie/sodium_compat) |
|
| 9 |
+[](https://packagist.org/packages/paragonie/sodium_compat) |
|
| 10 |
+ |
|
| 11 |
+Sodium Compat is a pure PHP polyfill for the Sodium cryptography library |
|
| 12 |
+(libsodium), a core extension in PHP 7.2.0+ and otherwise [available in PECL](https://pecl.php.net/package/libsodium). |
|
| 13 |
+ |
|
| 14 |
+This library tentativeley supports PHP 5.2.4 - 8.x (latest), but officially |
|
| 15 |
+only supports [non-EOL'd versions of PHP](https://secure.php.net/supported-versions.php). |
|
| 16 |
+ |
|
| 17 |
+If you have the PHP extension installed, Sodium Compat will opportunistically |
|
| 18 |
+and transparently use the PHP extension instead of our implementation. |
|
| 19 |
+ |
|
| 20 |
+## IMPORTANT! |
|
| 21 |
+ |
|
| 22 |
+This cryptography library has not been formally audited by an independent third |
|
| 23 |
+party that specializes in cryptography or cryptanalysis. |
|
| 24 |
+ |
|
| 25 |
+If you require such an audit before you can use sodium_compat in your projects |
|
| 26 |
+and have the funds for such an audit, please open an issue or contact |
|
| 27 |
+`security at paragonie dot com` so we can help get the ball rolling. |
|
| 28 |
+ |
|
| 29 |
+However, sodium_compat has been adopted by high profile open source projects, |
|
| 30 |
+such as [Joomla!](https://github.com/joomla/joomla-cms/blob/459d74686d2a638ec51149d7c44ddab8075852be/composer.json#L40) |
|
| 31 |
+and [Magento](https://github.com/magento/magento2/blob/8fd89cfdf52c561ac0ca7bc20fd38ef688e201b0/composer.json#L44). |
|
| 32 |
+Furthermore, sodium_compat was developed by Paragon Initiative Enterprises, a |
|
| 33 |
+company that *specializes* in secure PHP development and PHP cryptography, and |
|
| 34 |
+has been informally reviewed by many other security experts who also specialize |
|
| 35 |
+in PHP. |
|
| 36 |
+ |
|
| 37 |
+If you'd like to learn more about the defensive security measures we've taken |
|
| 38 |
+to prevent sodium_compat from being a source of vulnerability in your systems, |
|
| 39 |
+please read [*Cryptographically Secure PHP Development*](https://paragonie.com/blog/2017/02/cryptographically-secure-php-development). |
|
| 40 |
+ |
|
| 41 |
+# Installing Sodium Compat |
|
| 42 |
+ |
|
| 43 |
+If you're using Composer: |
|
| 44 |
+ |
|
| 45 |
+```bash |
|
| 46 |
+composer require paragonie/sodium_compat |
|
| 47 |
+``` |
|
| 48 |
+ |
|
| 49 |
+### Install From Source |
|
| 50 |
+ |
|
| 51 |
+If you're not using Composer, download a [release tarball](https://github.com/paragonie/sodium_compat/releases) |
|
| 52 |
+(which should be signed with [our GnuPG public key](https://paragonie.com/static/gpg-public-key.txt)), extract |
|
| 53 |
+its contents, then include our `autoload.php` script in your project. |
|
| 54 |
+ |
|
| 55 |
+```php |
|
| 56 |
+<?php |
|
| 57 |
+require_once "/path/to/sodium_compat/autoload.php"; |
|
| 58 |
+``` |
|
| 59 |
+ |
|
| 60 |
+### PHP Archives (Phar) Releases |
|
| 61 |
+ |
|
| 62 |
+Since version 1.3.0, [sodium_compat releases](https://github.com/paragonie/sodium_compat/releases) include a |
|
| 63 |
+PHP Archive (.phar file) and associated GPG signature. First, download both files and verify them with our |
|
| 64 |
+GPG public key, like so: |
|
| 65 |
+ |
|
| 66 |
+```bash |
|
| 67 |
+# Getting our public key from the keyserver: |
|
| 68 |
+gpg --fingerprint 7F52D5C61D1255C731362E826B97A1C2826404DA |
|
| 69 |
+if [ $? -ne 0 ]; then |
|
| 70 |
+ echo -e "\033[33mDownloading PGP Public Key...\033[0m" |
|
| 71 |
+ gpg --keyserver pgp.mit.edu --recv-keys 7F52D5C61D1255C731362E826B97A1C2826404DA |
|
| 72 |
+ # Security <security@paragonie.com> |
|
| 73 |
+ gpg --fingerprint 7F52D5C61D1255C731362E826B97A1C2826404DA |
|
| 74 |
+ if [ $? -ne 0 ]; then |
|
| 75 |
+ echo -e "\033[31mCould not download PGP public key for verification\033[0m" |
|
| 76 |
+ exit 1 |
|
| 77 |
+ fi |
|
| 78 |
+fi |
|
| 79 |
+ |
|
| 80 |
+# Verifying the PHP Archive |
|
| 81 |
+gpg --verify sodium-compat.phar.sig sodium-compat.phar |
|
| 82 |
+``` |
|
| 83 |
+ |
|
| 84 |
+Now, simply include this .phar file in your application. |
|
| 85 |
+ |
|
| 86 |
+```php |
|
| 87 |
+<?php |
|
| 88 |
+require_once "/path/to/sodium-compat.phar"; |
|
| 89 |
+``` |
|
| 90 |
+ |
|
| 91 |
+# Support |
|
| 92 |
+ |
|
| 93 |
+[Commercial support for libsodium](https://download.libsodium.org/doc/commercial_support/) is available |
|
| 94 |
+from multiple vendors. If you need help using sodium_compat in one of your projects, [contact Paragon Initiative Enterprises](https://paragonie.com/contact). |
|
| 95 |
+ |
|
| 96 |
+Non-commercial report will be facilitated through [Github issues](https://github.com/paragonie/sodium_compat/issues). |
|
| 97 |
+We offer no guarantees of our availability to resolve questions about integrating sodium_compat into third-party |
|
| 98 |
+software for free, but will strive to fix any bugs (security-related or otherwise) in our library. |
|
| 99 |
+ |
|
| 100 |
+## Support Contracts |
|
| 101 |
+ |
|
| 102 |
+If your company uses this library in their products or services, you may be |
|
| 103 |
+interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). |
|
| 104 |
+ |
|
| 105 |
+# Using Sodium Compat |
|
| 106 |
+ |
|
| 107 |
+## True Polyfill |
|
| 108 |
+ |
|
| 109 |
+If you're using PHP 5.3.0 or newer and do not have the PECL extension installed, |
|
| 110 |
+you can just use the [standard ext/sodium API features as-is](https://paragonie.com/book/pecl-libsodium) |
|
| 111 |
+and the polyfill will work its magic. |
|
| 112 |
+ |
|
| 113 |
+```php |
|
| 114 |
+<?php |
|
| 115 |
+require_once "/path/to/sodium_compat/autoload.php"; |
|
| 116 |
+ |
|
| 117 |
+$alice_kp = \Sodium\crypto_sign_keypair(); |
|
| 118 |
+$alice_sk = \Sodium\crypto_sign_secretkey($alice_kp); |
|
| 119 |
+$alice_pk = \Sodium\crypto_sign_publickey($alice_kp); |
|
| 120 |
+ |
|
| 121 |
+$message = 'This is a test message.'; |
|
| 122 |
+$signature = \Sodium\crypto_sign_detached($message, $alice_sk); |
|
| 123 |
+if (\Sodium\crypto_sign_verify_detached($signature, $message, $alice_pk)) {
|
|
| 124 |
+ echo 'OK', PHP_EOL; |
|
| 125 |
+} else {
|
|
| 126 |
+ throw new Exception('Invalid signature');
|
|
| 127 |
+} |
|
| 128 |
+``` |
|
| 129 |
+ |
|
| 130 |
+The polyfill does not expose this API on PHP < 5.3, or if you have the PHP |
|
| 131 |
+extension installed already. |
|
| 132 |
+ |
|
| 133 |
+## General-Use Polyfill |
|
| 134 |
+ |
|
| 135 |
+If your users are on PHP < 5.3, or you want to write code that will work |
|
| 136 |
+whether or not the PECL extension is available, you'll want to use the |
|
| 137 |
+**`ParagonIE_Sodium_Compat`** class for most of your libsodium needs. |
|
| 138 |
+ |
|
| 139 |
+The above example, written for general use: |
|
| 140 |
+ |
|
| 141 |
+```php |
|
| 142 |
+<?php |
|
| 143 |
+require_once "/path/to/sodium_compat/autoload.php"; |
|
| 144 |
+ |
|
| 145 |
+$alice_kp = ParagonIE_Sodium_Compat::crypto_sign_keypair(); |
|
| 146 |
+$alice_sk = ParagonIE_Sodium_Compat::crypto_sign_secretkey($alice_kp); |
|
| 147 |
+$alice_pk = ParagonIE_Sodium_Compat::crypto_sign_publickey($alice_kp); |
|
| 148 |
+ |
|
| 149 |
+$message = 'This is a test message.'; |
|
| 150 |
+$signature = ParagonIE_Sodium_Compat::crypto_sign_detached($message, $alice_sk); |
|
| 151 |
+if (ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $alice_pk)) {
|
|
| 152 |
+ echo 'OK', PHP_EOL; |
|
| 153 |
+} else {
|
|
| 154 |
+ throw new Exception('Invalid signature');
|
|
| 155 |
+} |
|
| 156 |
+``` |
|
| 157 |
+ |
|
| 158 |
+Generally: If you replace `\Sodium\ ` with `ParagonIE_Sodium_Compat::`, any |
|
| 159 |
+code already written for the libsodium PHP extension should work with our |
|
| 160 |
+polyfill without additional code changes. |
|
| 161 |
+ |
|
| 162 |
+Since this doesn't require a namespace, this API *is* exposed on PHP 5.2. |
|
| 163 |
+ |
|
| 164 |
+Since version 0.7.0, we have our own namespaced API (`ParagonIE\Sodium\*`) to allow brevity |
|
| 165 |
+in software that uses PHP 5.3+. This is useful if you want to use our file cryptography |
|
| 166 |
+features without writing `ParagonIE_Sodium_File` every time. This is not exposed on PHP < 5.3, |
|
| 167 |
+so if your project supports PHP < 5.3, use the underscore method instead. |
|
| 168 |
+ |
|
| 169 |
+To learn how to use Libsodium, read [*Using Libsodium in PHP Projects*](https://paragonie.com/book/pecl-libsodium). |
|
| 170 |
+ |
|
| 171 |
+## PHP 7.2 Polyfill |
|
| 172 |
+ |
|
| 173 |
+As per the [second vote on the libsodium RFC](https://wiki.php.net/rfc/libsodium#proposed_voting_choices), |
|
| 174 |
+PHP 7.2 uses `sodium_*` instead of `\Sodium\*`. |
|
| 175 |
+ |
|
| 176 |
+```php |
|
| 177 |
+<?php |
|
| 178 |
+require_once "/path/to/sodium_compat/autoload.php"; |
|
| 179 |
+ |
|
| 180 |
+$alice_kp = sodium_crypto_sign_keypair(); |
|
| 181 |
+$alice_sk = sodium_crypto_sign_secretkey($alice_kp); |
|
| 182 |
+$alice_pk = sodium_crypto_sign_publickey($alice_kp); |
|
| 183 |
+ |
|
| 184 |
+$message = 'This is a test message.'; |
|
| 185 |
+$signature = sodium_crypto_sign_detached($message, $alice_sk); |
|
| 186 |
+if (sodium_crypto_sign_verify_detached($signature, $message, $alice_pk)) {
|
|
| 187 |
+ echo 'OK', PHP_EOL; |
|
| 188 |
+} else {
|
|
| 189 |
+ throw new Exception('Invalid signature');
|
|
| 190 |
+} |
|
| 191 |
+``` |
|
| 192 |
+ |
|
| 193 |
+## Help, Sodium_Compat is Slow! How can I make it fast? |
|
| 194 |
+ |
|
| 195 |
+There are three ways to make it fast: |
|
| 196 |
+ |
|
| 197 |
+1. Use PHP 7.2. |
|
| 198 |
+2. [Install the libsodium PHP extension from PECL](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium). |
|
| 199 |
+3. Only if the previous two options are not available for you: |
|
| 200 |
+ 1. Verify that [the processor you're using actually implements constant-time multiplication](https://bearssl.org/ctmul.html). |
|
| 201 |
+ Sodium_compat does, but it must trade some speed in order to attain cross-platform security. |
|
| 202 |
+ 2. Only if you are 100% certain that your processor is safe, you can set `ParagonIE_Sodium_Compat::$fastMult = true;` |
|
| 203 |
+ without harming the security of your cryptography keys. If your processor *isn't* safe, then decide whether you |
|
| 204 |
+ want speed or security because you can't have both. |
|
| 205 |
+ |
|
| 206 |
+### How can I tell if sodium_compat will be slow, at runtime? |
|
| 207 |
+ |
|
| 208 |
+Since version 1.8, you can use the `polyfill_is_fast()` static method to |
|
| 209 |
+determine if sodium_compat will be slow at runtime. |
|
| 210 |
+ |
|
| 211 |
+```php |
|
| 212 |
+<?php |
|
| 213 |
+if (ParagonIE_Sodium_Compat::polyfill_is_fast()) {
|
|
| 214 |
+ // Use libsodium now |
|
| 215 |
+ $process->execute(); |
|
| 216 |
+} else {
|
|
| 217 |
+ // Defer to a cron job or other sort of asynchronous process |
|
| 218 |
+ $process->enqueue(); |
|
| 219 |
+} |
|
| 220 |
+``` |
|
| 221 |
+ |
|
| 222 |
+### Help, my PHP only has 32-Bit Integers! It's super slow! |
|
| 223 |
+ |
|
| 224 |
+Some features of sodium_compat are ***incredibly slow* with PHP 5 on Windows** |
|
| 225 |
+(in particular: public-key cryptography (encryption and signatures) is |
|
| 226 |
+affected), and there is nothing we can do about that, due to platform |
|
| 227 |
+restrictions on integers. |
|
| 228 |
+ |
|
| 229 |
+For acceptable performance, we highly recommend Windows users to version 1.0.6 |
|
| 230 |
+of the libsodium extension from PECL or, alternatively, simply upgrade to PHP 7 |
|
| 231 |
+and the slowdown will be greatly reduced. |
|
| 232 |
+ |
|
| 233 |
+This is also true of non-Windows 32-bit operating systems, or if somehow PHP |
|
| 234 |
+was compiled where `PHP_INT_SIZE` equals `4` instead of `8` (i.e. Linux on i386). |
|
| 235 |
+ |
|
| 236 |
+## Documentation |
|
| 237 |
+ |
|
| 238 |
+First, you'll want to read the [Libsodium Quick Reference](https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use). |
|
| 239 |
+It aims to answer, "Which function should I use for [common problem]?". |
|
| 240 |
+ |
|
| 241 |
+If you don't find the answers in the Quick Reference page, check out |
|
| 242 |
+[*Using Libsodium in PHP Projects*](https://paragonie.com/book/pecl-libsodium). |
|
| 243 |
+ |
|
| 244 |
+Finally, the [official libsodium documentation](https://download.libsodium.org/doc/) |
|
| 245 |
+(which was written for the C library, not the PHP library) also contains a lot of |
|
| 246 |
+insightful technical information you may find helpful. |
|
| 247 |
+ |
|
| 248 |
+## API Coverage |
|
| 249 |
+ |
|
| 250 |
+**Recommended reading:** [Libsodium Quick Reference](https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use) |
|
| 251 |
+ |
|
| 252 |
+* Mainline NaCl Features |
|
| 253 |
+ * `crypto_auth()` |
|
| 254 |
+ * `crypto_auth_verify()` |
|
| 255 |
+ * `crypto_box()` |
|
| 256 |
+ * `crypto_box_open()` |
|
| 257 |
+ * `crypto_scalarmult()` |
|
| 258 |
+ * `crypto_secretbox()` |
|
| 259 |
+ * `crypto_secretbox_open()` |
|
| 260 |
+ * `crypto_sign()` |
|
| 261 |
+ * `crypto_sign_open()` |
|
| 262 |
+* PECL Libsodium Features |
|
| 263 |
+ * `crypto_aead_aes256gcm_encrypt()` |
|
| 264 |
+ * `crypto_aead_aes256gcm_decrypt()` |
|
| 265 |
+ * `crypto_aead_chacha20poly1305_encrypt()` |
|
| 266 |
+ * `crypto_aead_chacha20poly1305_decrypt()` |
|
| 267 |
+ * `crypto_aead_chacha20poly1305_ietf_encrypt()` |
|
| 268 |
+ * `crypto_aead_chacha20poly1305_ietf_decrypt()` |
|
| 269 |
+ * `crypto_aead_xchacha20poly1305_ietf_encrypt()` |
|
| 270 |
+ * `crypto_aead_xchacha20poly1305_ietf_decrypt()` |
|
| 271 |
+ * `crypto_box_xchacha20poly1305()` |
|
| 272 |
+ * `crypto_box_xchacha20poly1305_open()` |
|
| 273 |
+ * `crypto_box_seal()` |
|
| 274 |
+ * `crypto_box_seal_open()` |
|
| 275 |
+ * `crypto_generichash()` |
|
| 276 |
+ * `crypto_generichash_init()` |
|
| 277 |
+ * `crypto_generichash_update()` |
|
| 278 |
+ * `crypto_generichash_final()` |
|
| 279 |
+ * `crypto_kx()` |
|
| 280 |
+ * `crypto_secretbox_xchacha20poly1305()` |
|
| 281 |
+ * `crypto_secretbox_xchacha20poly1305_open()` |
|
| 282 |
+ * `crypto_shorthash()` |
|
| 283 |
+ * `crypto_sign_detached()` |
|
| 284 |
+ * `crypto_sign_ed25519_pk_to_curve25519()` |
|
| 285 |
+ * `crypto_sign_ed25519_sk_to_curve25519()` |
|
| 286 |
+ * `crypto_sign_verify_detached()` |
|
| 287 |
+ * For advanced users only: |
|
| 288 |
+ * `crypto_stream()` |
|
| 289 |
+ * `crypto_stream_xor()` |
|
| 290 |
+ * Other utilities (e.g. `crypto_*_keypair()`) |
|
| 291 |
+ * `add()` |
|
| 292 |
+ * `base642bin()` |
|
| 293 |
+ * `bin2base64()` |
|
| 294 |
+ * `bin2hex()` |
|
| 295 |
+ * `hex2bin()` |
|
| 296 |
+ * `crypto_kdf_derive_from_key()` |
|
| 297 |
+ * `crypto_kx_client_session_keys()` |
|
| 298 |
+ * `crypto_kx_server_session_keys()` |
|
| 299 |
+ * `crypto_secretstream_xchacha20poly1305_init_push()` |
|
| 300 |
+ * `crypto_secretstream_xchacha20poly1305_push()` |
|
| 301 |
+ * `crypto_secretstream_xchacha20poly1305_init_pull()` |
|
| 302 |
+ * `crypto_secretstream_xchacha20poly1305_pull()` |
|
| 303 |
+ * `crypto_secretstream_xchacha20poly1305_rekey()` |
|
| 304 |
+ * `pad()` |
|
| 305 |
+ * `unpad()` |
|
| 306 |
+ |
|
| 307 |
+### Cryptography Primitives Provided |
|
| 308 |
+ |
|
| 309 |
+* **X25519** - Elliptic Curve Diffie Hellman over Curve25519 |
|
| 310 |
+* **Ed25519** - Edwards curve Digital Signature Algorithm over Curve25519 |
|
| 311 |
+* **Xsalsa20** - Extended-nonce Salsa20 stream cipher |
|
| 312 |
+* **ChaCha20** - Stream cipher |
|
| 313 |
+* **Xchacha20** - Extended-nonce ChaCha20 stream cipher |
|
| 314 |
+* **Poly1305** - Polynomial Evaluation Message Authentication Code modulo 2^130 - 5 |
|
| 315 |
+* **BLAKE2b** - Cryptographic Hash Function |
|
| 316 |
+* **SipHash-2-4** - Fast hash, but not collision-resistant; ideal for hash tables. |
|
| 317 |
+ |
|
| 318 |
+### Features Excluded from this Polyfill |
|
| 319 |
+ |
|
| 320 |
+* `\Sodium\memzero()` - Although we expose this API endpoint, we can't reliably |
|
| 321 |
+ zero buffers from PHP. |
|
| 322 |
+ |
|
| 323 |
+ If you have the PHP extension installed, sodium_compat |
|
| 324 |
+ will use the native implementation to zero out the string provided. Otherwise |
|
| 325 |
+ it will throw a `SodiumException`. |
|
| 326 |
+* `\Sodium\crypto_pwhash()` - It's not feasible to polyfill scrypt or Argon2 |
|
| 327 |
+ into PHP and get reasonable performance. Users would feel motivated to select |
|
| 328 |
+ parameters that downgrade security to avoid denial of service (DoS) attacks. |
|
| 329 |
+ |
|
| 330 |
+ The only winning move is not to play. |
|
| 331 |
+ |
|
| 332 |
+ If ext/sodium or ext/libsodium is installed, these API methods will fallthrough |
|
| 333 |
+ to the extension. Otherwise, our polyfill library will throw a `SodiumException`. |
|
| 334 |
+ |
|
| 335 |
+ To detect support for Argon2i at runtime, use |
|
| 336 |
+ `ParagonIE_Sodium_Compat::crypto_pwhash_is_available()`, which returns a |
|
| 337 |
+ boolean value (`TRUE` or `FALSE`). |
|
| 338 |
+ |
|
| 339 |
+### PHPCompatibility Ruleset |
|
| 340 |
+ |
|
| 341 |
+For sodium_compat users and that utilize [`PHPCompatibility`](https://github.com/PHPCompatibility/PHPCompatibility) |
|
| 342 |
+in their CI process, there is now a custom ruleset available which can be used |
|
| 343 |
+to prevent false positives being thrown by `PHPCompatibility` for the native |
|
| 344 |
+PHP functionality being polyfilled by this repo. |
|
| 345 |
+ |
|
| 346 |
+You can find the repo for the `PHPCompatibilityParagonieSodiumCompat` ruleset |
|
| 347 |
+here [on Github](https://github.com/PHPCompatibility/PHPCompatibilityParagonie) |
|
| 348 |
+and [on Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie). |