Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:103331 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 14006 invoked from network); 19 Oct 2018 04:24:47 -0000 Received: from unknown (HELO mail-lf1-f54.google.com) (209.85.167.54) by pb1.pair.com with SMTP; 19 Oct 2018 04:24:47 -0000 Received: by mail-lf1-f54.google.com with SMTP id m18-v6so23966110lfl.11 for ; Thu, 18 Oct 2018 17:38:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sammyk-me.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=PyjLnFTYeY3TFOgV1gHxqL7yZnveGs/w1o19S5bJ16U=; b=wcJfE+ZFcSZxXGjloFwIVkk0UYTMjZdcyoNSBvtgbieitXYNIXkS7WO9H1pbRjy/5g zRb96IqEFIK48ajmH3eT2+yMdiafbmgvwwgSqshmZ92iIQbpjW15L+kZy8nSRPKEoyGg sqBOcJj6Q5StpYjT3huJ9+lfWdoDOAgB9OHP7F60ats63yLne9QjdupqSr/fLYqx9XJY 8mKcFzqwntb6Ho9Y7rJwCeJJ/uSqDtx1ADnrKekNI1VVIZA+GRQL0hDYl78kwu7lnvBc XRxPagr7gPWEHoAer4BXzJJ58EGh6Hefhd+pSp4DNjk5jDClDWVxjRlJ6/+9wA6D2Ms1 zA3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=PyjLnFTYeY3TFOgV1gHxqL7yZnveGs/w1o19S5bJ16U=; b=Y49Bt4MRL5dnE62KJ0zMlL4q4prthcjiYPE+HtYxmFMialdi2sO3341qsuVOLzMJoe 6QijlHn9vDHae/pbETTL/yLZM8XFcJOQiHQKtmMTX+z6X7Op5Rt2LCP50+0XiWQf/D6q PnsxC5kJ0T7OfYCdYzgrievRrqe8yGiLaoEN5lUGdIYzqA0rTMK7MWxSx/ReSOFmvYmn j4psaAlP4CRDK7eANd+fLKb2Wl4gp17os7c38N98HJqi3vZxpoulx2TTXdRUbA/mk+Sa dSjEzzQtgxTL8ImEFtG3d2N32Ib/lHPNGY1y7dYqmsOeTcwsSU1QYj8P2ZiTmkq74Ziz jFKw== X-Gm-Message-State: ABuFfohndJzlzf6sTnewGJtR6Wm9gCEvFucUbrFhLKCkDvyc48NcOYhw L0KfVjAOLOf9HTLAybBeLA7THtXnIcvXGZpu5zHKBrA9FOI= X-Google-Smtp-Source: ACcGV63RmXu4M7JDpzPe4tVlawnjn9+zrS+Hu85ljsTNc4qNeKzv53coReQplWaXjfVspp5J9ceFGwpVKlX6mQquXwA= X-Received: by 2002:a19:964e:: with SMTP id y75-v6mr1555856lfd.58.1539909510711; Thu, 18 Oct 2018 17:38:30 -0700 (PDT) MIME-Version: 1.0 Date: Thu, 18 Oct 2018 17:38:19 -0700 Message-ID: To: PHP Internals Content-Type: text/plain; charset="UTF-8" Subject: Alias openssl_random_pseudo_bytes() to php_random_bytes_throw() From: me@sammyk.me (Sammy Kaye Powers) Hello internals friends! I wanted to propose aliasing openssl_random_pseudo_bytes() to php_random_bytes_throw() in PHP 7.4 for the following reasons: 1) OpenSSL's CSPRNG isn't fork safe: https://wiki.openssl.org/index.php/Random_fork-safety This did get fixed last month with the release of v1.1.1 with a complete rewrite of their CSPRNG, but my guess is it'll be a while before we see that version landing in a LTS distro. 2) The openssl_random_pseudo_bytes() function fails open which means code like this: function genCsrfToken(): string { return bin2hex(openssl_random_pseudo_bytes(32)); } ...could return an empty string. This forces the developer to do their own checks and fail closed in userland. function genCsrfToken(): string { $bytes = openssl_random_pseudo_bytes(32); if (false === $bytes) { throw new \Exception('CSPRNG error'); } return bin2hex($bytes); } A quick search in GitHub reveals very little checking of the return value of openssl_random_pseudo_bytes() in the wild. CSPRNG implementations should always fail closed. 3) It gets worse: there's that confusing pass-by-reference param zstrong_result_returned that forces yet another check in userland to determine if the bytes are strong enough for crypto. To be honest, in checking the implementation, I can't even tell how the function would ever return a string of bytes and also set the zstrong_result_returned param to false. The API is unnecessarily confusing making it easy to get it wrong. The above userland example isn't even correct, the correct usage in userland would actually be: function genCsrfToken(): string { $strong = false; $bytes = openssl_random_pseudo_bytes(32, $strong); if (false === $bytes || false === $strong) { throw new \Exception('CSPRNG error'); } return bin2hex($bytes); } 4) We get to consolidate our CSPRNG code in one place. This would make it nice to be able to upgrade all the CSPRNG code to libsodium's CSPRNG if we choose to in the future for example. The change I'm proposing would be to: 1) Make openssl_random_pseudo_bytes() return bytes from php_random_bytes_throw() causing the function to fail closed and never returning false. 2) Deprecate the usage of the second pass-by-reference parameter and remove in PHP 8.0. Until then, it always sets the value to true. Do you think this kind of change would warrant an RFC? Thanks, Sammy Kaye Powers sammyk.me