[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/ -> RSA.php (source)

   1  <?php
   2  
   3  /**
   4   * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
   5   *
   6   * PHP version 5
   7   *
   8   * Here's an example of how to encrypt and decrypt text with this library:
   9   * <code>
  10   * <?php
  11   * include 'vendor/autoload.php';
  12   *
  13   * $private = \phpseclib3\Crypt\RSA::createKey();
  14   * $public = $private->getPublicKey();
  15   *
  16   * $plaintext = 'terrafrost';
  17   *
  18   * $ciphertext = $public->encrypt($plaintext);
  19   *
  20   * echo $private->decrypt($ciphertext);
  21   * ?>
  22   * </code>
  23   *
  24   * Here's an example of how to create signatures and verify signatures with this library:
  25   * <code>
  26   * <?php
  27   * include 'vendor/autoload.php';
  28   *
  29   * $private = \phpseclib3\Crypt\RSA::createKey();
  30   * $public = $private->getPublicKey();
  31   *
  32   * $plaintext = 'terrafrost';
  33   *
  34   * $signature = $private->sign($plaintext);
  35   *
  36   * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified';
  37   * ?>
  38   * </code>
  39   *
  40   * One thing to consider when using this: so phpseclib uses PSS mode by default.
  41   * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So
  42   * should phpseclib save to the id-RSASSA-PSS format by default or the
  43   * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better
  44   * because SSH doesn't use PSS and idk how many SSH servers would be able to
  45   * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS
  46   * format is used by default (unless you change it up to use PKCS1 instead)
  47   *
  48   * @author    Jim Wigginton <terrafrost@php.net>
  49   * @copyright 2009 Jim Wigginton
  50   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  51   * @link      http://phpseclib.sourceforge.net
  52   */
  53  
  54  namespace phpseclib3\Crypt;
  55  
  56  use phpseclib3\Crypt\Common\AsymmetricKey;
  57  use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
  58  use phpseclib3\Crypt\RSA\PrivateKey;
  59  use phpseclib3\Crypt\RSA\PublicKey;
  60  use phpseclib3\Exception\InconsistentSetupException;
  61  use phpseclib3\Exception\UnsupportedAlgorithmException;
  62  use phpseclib3\Math\BigInteger;
  63  
  64  /**
  65   * Pure-PHP PKCS#1 compliant implementation of RSA.
  66   *
  67   * @author  Jim Wigginton <terrafrost@php.net>
  68   */
  69  abstract class RSA extends AsymmetricKey
  70  {
  71      /**
  72       * Algorithm Name
  73       *
  74       * @var string
  75       */
  76      const ALGORITHM = 'RSA';
  77  
  78      /**
  79       * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
  80       * (OAEP) for encryption / decryption.
  81       *
  82       * Uses sha256 by default
  83       *
  84       * @see self::setHash()
  85       * @see self::setMGFHash()
  86       * @see self::encrypt()
  87       * @see self::decrypt()
  88       */
  89      const ENCRYPTION_OAEP = 1;
  90  
  91      /**
  92       * Use PKCS#1 padding.
  93       *
  94       * Although self::PADDING_OAEP / self::PADDING_PSS  offers more security, including PKCS#1 padding is necessary for purposes of backwards
  95       * compatibility with protocols (like SSH-1) written before OAEP's introduction.
  96       *
  97       * @see self::encrypt()
  98       * @see self::decrypt()
  99       */
 100      const ENCRYPTION_PKCS1 = 2;
 101  
 102      /**
 103       * Do not use any padding
 104       *
 105       * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
 106       * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
 107       *
 108       * @see self::encrypt()
 109       * @see self::decrypt()
 110       */
 111      const ENCRYPTION_NONE = 4;
 112  
 113      /**
 114       * Use the Probabilistic Signature Scheme for signing
 115       *
 116       * Uses sha256 and 0 as the salt length
 117       *
 118       * @see self::setSaltLength()
 119       * @see self::setMGFHash()
 120       * @see self::setHash()
 121       * @see self::sign()
 122       * @see self::verify()
 123       * @see self::setHash()
 124       */
 125      const SIGNATURE_PSS = 16;
 126  
 127      /**
 128       * Use a relaxed version of PKCS#1 padding for signature verification
 129       *
 130       * @see self::sign()
 131       * @see self::verify()
 132       * @see self::setHash()
 133       */
 134      const SIGNATURE_RELAXED_PKCS1 = 32;
 135  
 136      /**
 137       * Use PKCS#1 padding for signature verification
 138       *
 139       * @see self::sign()
 140       * @see self::verify()
 141       * @see self::setHash()
 142       */
 143      const SIGNATURE_PKCS1 = 64;
 144  
 145      /**
 146       * Encryption padding mode
 147       *
 148       * @var int
 149       */
 150      protected $encryptionPadding = self::ENCRYPTION_OAEP;
 151  
 152      /**
 153       * Signature padding mode
 154       *
 155       * @var int
 156       */
 157      protected $signaturePadding = self::SIGNATURE_PSS;
 158  
 159      /**
 160       * Length of hash function output
 161       *
 162       * @var int
 163       */
 164      protected $hLen;
 165  
 166      /**
 167       * Length of salt
 168       *
 169       * @var int
 170       */
 171      protected $sLen;
 172  
 173      /**
 174       * Label
 175       *
 176       * @var string
 177       */
 178      protected $label = '';
 179  
 180      /**
 181       * Hash function for the Mask Generation Function
 182       *
 183       * @var \phpseclib3\Crypt\Hash
 184       */
 185      protected $mgfHash;
 186  
 187      /**
 188       * Length of MGF hash function output
 189       *
 190       * @var int
 191       */
 192      protected $mgfHLen;
 193  
 194      /**
 195       * Modulus (ie. n)
 196       *
 197       * @var \phpseclib3\Math\BigInteger
 198       */
 199      protected $modulus;
 200  
 201      /**
 202       * Modulus length
 203       *
 204       * @var \phpseclib3\Math\BigInteger
 205       */
 206      protected $k;
 207  
 208      /**
 209       * Exponent (ie. e or d)
 210       *
 211       * @var \phpseclib3\Math\BigInteger
 212       */
 213      protected $exponent;
 214  
 215      /**
 216       * Default public exponent
 217       *
 218       * @var int
 219       * @link http://en.wikipedia.org/wiki/65537_%28number%29
 220       */
 221      private static $defaultExponent = 65537;
 222  
 223      /**
 224       * Enable Blinding?
 225       *
 226       * @var bool
 227       */
 228      protected static $enableBlinding = true;
 229  
 230      /**
 231       * OpenSSL configuration file name.
 232       *
 233       * @see self::createKey()
 234       * @var ?string
 235       */
 236      protected static $configFile;
 237  
 238      /**
 239       * Smallest Prime
 240       *
 241       * Per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
 242       * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime
 243       * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if
 244       * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is
 245       * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's
 246       * a chance neither gmp nor OpenSSL are installed)
 247       *
 248       * @var int
 249       */
 250      private static $smallestPrime = 4096;
 251  
 252      /**
 253       * Public Exponent
 254       *
 255       * @var \phpseclib3\Math\BigInteger
 256       */
 257      protected $publicExponent;
 258  
 259      /**
 260       * Sets the public exponent for key generation
 261       *
 262       * This will be 65537 unless changed.
 263       *
 264       * @param int $val
 265       */
 266      public static function setExponent($val)
 267      {
 268          self::$defaultExponent = $val;
 269      }
 270  
 271      /**
 272       * Sets the smallest prime number in bits. Used for key generation
 273       *
 274       * This will be 4096 unless changed.
 275       *
 276       * @param int $val
 277       */
 278      public static function setSmallestPrime($val)
 279      {
 280          self::$smallestPrime = $val;
 281      }
 282  
 283      /**
 284       * Sets the OpenSSL config file path
 285       *
 286       * Set to the empty string to use the default config file
 287       *
 288       * @param string $val
 289       */
 290      public static function setOpenSSLConfigPath($val)
 291      {
 292          self::$configFile = $val;
 293      }
 294  
 295      /**
 296       * Create a private key
 297       *
 298       * The public key can be extracted from the private key
 299       *
 300       * @return RSA\PrivateKey
 301       * @param int $bits
 302       */
 303      public static function createKey($bits = 2048)
 304      {
 305          self::initialize_static_variables();
 306  
 307          $class = new \ReflectionClass(static::class);
 308          if ($class->isFinal()) {
 309              throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')');
 310          }
 311  
 312          $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be
 313          if ($regSize > self::$smallestPrime) {
 314              $num_primes = floor($bits / self::$smallestPrime);
 315              $regSize = self::$smallestPrime;
 316          } else {
 317              $num_primes = 2;
 318          }
 319  
 320          if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) {
 321              if (!isset(self::$engines['PHP'])) {
 322                  self::useBestEngine();
 323              }
 324  
 325              // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
 326              if (self::$engines['OpenSSL']) {
 327                  $config = [];
 328                  if (self::$configFile) {
 329                      $config['config'] = self::$configFile;
 330                  }
 331                  $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config);
 332                  openssl_pkey_export($rsa, $privatekeystr, null, $config);
 333  
 334                  // clear the buffer of error strings stemming from a minimalistic openssl.cnf
 335                  // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up
 336                  while (openssl_error_string() !== false) {
 337                  }
 338  
 339                  return RSA::load($privatekeystr);
 340              }
 341          }
 342  
 343          static $e;
 344          if (!isset($e)) {
 345              $e = new BigInteger(self::$defaultExponent);
 346          }
 347  
 348          $n = clone self::$one;
 349          $exponents = $coefficients = $primes = [];
 350          $lcm = [
 351              'top' => clone self::$one,
 352              'bottom' => false
 353          ];
 354  
 355          do {
 356              for ($i = 1; $i <= $num_primes; $i++) {
 357                  if ($i != $num_primes) {
 358                      $primes[$i] = BigInteger::randomPrime($regSize);
 359                  } else {
 360                      extract(BigInteger::minMaxBits($bits));
 361                      /** @var BigInteger $min
 362                       *  @var BigInteger $max
 363                       */
 364                      list($min) = $min->divide($n);
 365                      $min = $min->add(self::$one);
 366                      list($max) = $max->divide($n);
 367                      $primes[$i] = BigInteger::randomRangePrime($min, $max);
 368                  }
 369  
 370                  // the first coefficient is calculated differently from the rest
 371                  // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
 372                  if ($i > 2) {
 373                      $coefficients[$i] = $n->modInverse($primes[$i]);
 374                  }
 375  
 376                  $n = $n->multiply($primes[$i]);
 377  
 378                  $temp = $primes[$i]->subtract(self::$one);
 379  
 380                  // textbook RSA implementations use Euler's totient function instead of the least common multiple.
 381                  // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
 382                  $lcm['top'] = $lcm['top']->multiply($temp);
 383                  $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
 384              }
 385  
 386              list($temp) = $lcm['top']->divide($lcm['bottom']);
 387              $gcd = $temp->gcd($e);
 388              $i0 = 1;
 389          } while (!$gcd->equals(self::$one));
 390  
 391          $coefficients[2] = $primes[2]->modInverse($primes[1]);
 392  
 393          $d = $e->modInverse($temp);
 394  
 395          foreach ($primes as $i => $prime) {
 396              $temp = $prime->subtract(self::$one);
 397              $exponents[$i] = $e->modInverse($temp);
 398          }
 399  
 400          // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
 401          // RSAPrivateKey ::= SEQUENCE {
 402          //     version           Version,
 403          //     modulus           INTEGER,  -- n
 404          //     publicExponent    INTEGER,  -- e
 405          //     privateExponent   INTEGER,  -- d
 406          //     prime1            INTEGER,  -- p
 407          //     prime2            INTEGER,  -- q
 408          //     exponent1         INTEGER,  -- d mod (p-1)
 409          //     exponent2         INTEGER,  -- d mod (q-1)
 410          //     coefficient       INTEGER,  -- (inverse of q) mod p
 411          //     otherPrimeInfos   OtherPrimeInfos OPTIONAL
 412          // }
 413          $privatekey = new PrivateKey();
 414          $privatekey->modulus = $n;
 415          $privatekey->k = $bits >> 3;
 416          $privatekey->publicExponent = $e;
 417          $privatekey->exponent = $d;
 418          $privatekey->primes = $primes;
 419          $privatekey->exponents = $exponents;
 420          $privatekey->coefficients = $coefficients;
 421  
 422          /*
 423          $publickey = new PublicKey;
 424          $publickey->modulus = $n;
 425          $publickey->k = $bits >> 3;
 426          $publickey->exponent = $e;
 427          $publickey->publicExponent = $e;
 428          $publickey->isPublic = true;
 429          */
 430  
 431          return $privatekey;
 432      }
 433  
 434      /**
 435       * OnLoad Handler
 436       *
 437       * @return bool
 438       */
 439      protected static function onLoad(array $components)
 440      {
 441          $key = $components['isPublicKey'] ?
 442              new PublicKey() :
 443              new PrivateKey();
 444  
 445          $key->modulus = $components['modulus'];
 446          $key->publicExponent = $components['publicExponent'];
 447          $key->k = $key->modulus->getLengthInBytes();
 448  
 449          if ($components['isPublicKey'] || !isset($components['privateExponent'])) {
 450              $key->exponent = $key->publicExponent;
 451          } else {
 452              $key->privateExponent = $components['privateExponent'];
 453              $key->exponent = $key->privateExponent;
 454              $key->primes = $components['primes'];
 455              $key->exponents = $components['exponents'];
 456              $key->coefficients = $components['coefficients'];
 457          }
 458  
 459          if ($components['format'] == PSS::class) {
 460              // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is
 461              // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib
 462              // uses PSS padding by default. it assumes the more secure method by default and altho it provides
 463              // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent
 464              // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that
 465              // not only does it defaults to the most secure methods - it doesn't even let you choose less
 466              // secure methods
 467              //$key = $key->withPadding(self::SIGNATURE_PSS);
 468              if (isset($components['hash'])) {
 469                  $key = $key->withHash($components['hash']);
 470              }
 471              if (isset($components['MGFHash'])) {
 472                  $key = $key->withMGFHash($components['MGFHash']);
 473              }
 474              if (isset($components['saltLength'])) {
 475                  $key = $key->withSaltLength($components['saltLength']);
 476              }
 477          }
 478  
 479          return $key;
 480      }
 481  
 482      /**
 483       * Initialize static variables
 484       */
 485      protected static function initialize_static_variables()
 486      {
 487          if (!isset(self::$configFile)) {
 488              self::$configFile = dirname(__FILE__) . '/../openssl.cnf';
 489          }
 490  
 491          parent::initialize_static_variables();
 492      }
 493  
 494      /**
 495       * Constructor
 496       *
 497       * PublicKey and PrivateKey objects can only be created from abstract RSA class
 498       */
 499      protected function __construct()
 500      {
 501          parent::__construct();
 502  
 503          $this->hLen = $this->hash->getLengthInBytes();
 504          $this->mgfHash = new Hash('sha256');
 505          $this->mgfHLen = $this->mgfHash->getLengthInBytes();
 506      }
 507  
 508      /**
 509       * Integer-to-Octet-String primitive
 510       *
 511       * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
 512       *
 513       * @param bool|\phpseclib3\Math\BigInteger $x
 514       * @param int $xLen
 515       * @return bool|string
 516       */
 517      protected function i2osp($x, $xLen)
 518      {
 519          if ($x === false) {
 520              return false;
 521          }
 522          $x = $x->toBytes();
 523          if (strlen($x) > $xLen) {
 524              throw new \OutOfRangeException('Resultant string length out of range');
 525          }
 526          return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
 527      }
 528  
 529      /**
 530       * Octet-String-to-Integer primitive
 531       *
 532       * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
 533       *
 534       * @param string $x
 535       * @return \phpseclib3\Math\BigInteger
 536       */
 537      protected function os2ip($x)
 538      {
 539          return new BigInteger($x, 256);
 540      }
 541  
 542      /**
 543       * EMSA-PKCS1-V1_5-ENCODE
 544       *
 545       * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
 546       *
 547       * @param string $m
 548       * @param int $emLen
 549       * @throws \LengthException if the intended encoded message length is too short
 550       * @return string
 551       */
 552      protected function emsa_pkcs1_v1_5_encode($m, $emLen)
 553      {
 554          $h = $this->hash->hash($m);
 555  
 556          // see http://tools.ietf.org/html/rfc3447#page-43
 557          switch ($this->hash->getHash()) {
 558              case 'md2':
 559                  $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10";
 560                  break;
 561              case 'md5':
 562                  $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
 563                  break;
 564              case 'sha1':
 565                  $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14";
 566                  break;
 567              case 'sha256':
 568                  $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
 569                  break;
 570              case 'sha384':
 571                  $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30";
 572                  break;
 573              case 'sha512':
 574                  $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40";
 575                  break;
 576              // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
 577              case 'sha224':
 578                  $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c";
 579                  break;
 580              case 'sha512/224':
 581                  $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c";
 582                  break;
 583              case 'sha512/256':
 584                  $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20";
 585          }
 586          $t .= $h;
 587          $tLen = strlen($t);
 588  
 589          if ($emLen < $tLen + 11) {
 590              throw new \LengthException('Intended encoded message length too short');
 591          }
 592  
 593          $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
 594  
 595          $em = "\0\1$ps\0$t";
 596  
 597          return $em;
 598      }
 599  
 600      /**
 601       * EMSA-PKCS1-V1_5-ENCODE (without NULL)
 602       *
 603       * Quoting https://tools.ietf.org/html/rfc8017#page-65,
 604       *
 605       * "The parameters field associated with id-sha1, id-sha224, id-sha256,
 606       *  id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
 607       *  generally be omitted, but if present, it shall have a value of type
 608       *  NULL"
 609       *
 610       * @param string $m
 611       * @param int $emLen
 612       * @return string
 613       */
 614      protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
 615      {
 616          $h = $this->hash->hash($m);
 617  
 618          // see http://tools.ietf.org/html/rfc3447#page-43
 619          switch ($this->hash->getHash()) {
 620              case 'sha1':
 621                  $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14";
 622                  break;
 623              case 'sha256':
 624                  $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20";
 625                  break;
 626              case 'sha384':
 627                  $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30";
 628                  break;
 629              case 'sha512':
 630                  $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40";
 631                  break;
 632              // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
 633              case 'sha224':
 634                  $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c";
 635                  break;
 636              case 'sha512/224':
 637                  $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c";
 638                  break;
 639              case 'sha512/256':
 640                  $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20";
 641                  break;
 642              default:
 643                  throw new UnsupportedAlgorithmException('md2 and md5 require NULLs');
 644          }
 645          $t .= $h;
 646          $tLen = strlen($t);
 647  
 648          if ($emLen < $tLen + 11) {
 649              throw new \LengthException('Intended encoded message length too short');
 650          }
 651  
 652          $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
 653  
 654          $em = "\0\1$ps\0$t";
 655  
 656          return $em;
 657      }
 658  
 659      /**
 660       * MGF1
 661       *
 662       * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
 663       *
 664       * @param string $mgfSeed
 665       * @param int $maskLen
 666       * @return string
 667       */
 668      protected function mgf1($mgfSeed, $maskLen)
 669      {
 670          // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
 671  
 672          $t = '';
 673          $count = ceil($maskLen / $this->mgfHLen);
 674          for ($i = 0; $i < $count; $i++) {
 675              $c = pack('N', $i);
 676              $t .= $this->mgfHash->hash($mgfSeed . $c);
 677          }
 678  
 679          return substr($t, 0, $maskLen);
 680      }
 681  
 682      /**
 683       * Returns the key size
 684       *
 685       * More specifically, this returns the size of the modulo in bits.
 686       *
 687       * @return int
 688       */
 689      public function getLength()
 690      {
 691          return !isset($this->modulus) ? 0 : $this->modulus->getLength();
 692      }
 693  
 694      /**
 695       * Determines which hashing function should be used
 696       *
 697       * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and
 698       * decryption.
 699       *
 700       * @param string $hash
 701       */
 702      public function withHash($hash)
 703      {
 704          $new = clone $this;
 705  
 706          // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
 707          switch (strtolower($hash)) {
 708              case 'md2':
 709              case 'md5':
 710              case 'sha1':
 711              case 'sha256':
 712              case 'sha384':
 713              case 'sha512':
 714              case 'sha224':
 715              case 'sha512/224':
 716              case 'sha512/256':
 717                  $new->hash = new Hash($hash);
 718                  break;
 719              default:
 720                  throw new UnsupportedAlgorithmException(
 721                      'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
 722                  );
 723          }
 724          $new->hLen = $new->hash->getLengthInBytes();
 725  
 726          return $new;
 727      }
 728  
 729      /**
 730       * Determines which hashing function should be used for the mask generation function
 731       *
 732       * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's
 733       * best if Hash and MGFHash are set to the same thing this is not a requirement.
 734       *
 735       * @param string $hash
 736       */
 737      public function withMGFHash($hash)
 738      {
 739          $new = clone $this;
 740  
 741          // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
 742          switch (strtolower($hash)) {
 743              case 'md2':
 744              case 'md5':
 745              case 'sha1':
 746              case 'sha256':
 747              case 'sha384':
 748              case 'sha512':
 749              case 'sha224':
 750              case 'sha512/224':
 751              case 'sha512/256':
 752                  $new->mgfHash = new Hash($hash);
 753                  break;
 754              default:
 755                  throw new UnsupportedAlgorithmException(
 756                      'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
 757                  );
 758          }
 759          $new->mgfHLen = $new->mgfHash->getLengthInBytes();
 760  
 761          return $new;
 762      }
 763  
 764      /**
 765       * Returns the MGF hash algorithm currently being used
 766       *
 767       */
 768      public function getMGFHash()
 769      {
 770          return clone $this->mgfHash;
 771      }
 772  
 773      /**
 774       * Determines the salt length
 775       *
 776       * Used by RSA::PADDING_PSS
 777       *
 778       * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
 779       *
 780       *    Typical salt lengths in octets are hLen (the length of the output
 781       *    of the hash function Hash) and 0.
 782       *
 783       * @param int $sLen
 784       */
 785      public function withSaltLength($sLen)
 786      {
 787          $new = clone $this;
 788          $new->sLen = $sLen;
 789          return $new;
 790      }
 791  
 792      /**
 793       * Returns the salt length currently being used
 794       *
 795       */
 796      public function getSaltLength()
 797      {
 798          return $this->sLen !== null ? $this->sLen : $this->hLen;
 799      }
 800  
 801      /**
 802       * Determines the label
 803       *
 804       * Used by RSA::PADDING_OAEP
 805       *
 806       * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
 807       *
 808       *    Both the encryption and the decryption operations of RSAES-OAEP take
 809       *    the value of a label L as input.  In this version of PKCS #1, L is
 810       *    the empty string; other uses of the label are outside the scope of
 811       *    this document.
 812       *
 813       * @param string $label
 814       */
 815      public function withLabel($label)
 816      {
 817          $new = clone $this;
 818          $new->label = $label;
 819          return $new;
 820      }
 821  
 822      /**
 823       * Returns the label currently being used
 824       *
 825       */
 826      public function getLabel()
 827      {
 828          return $this->label;
 829      }
 830  
 831      /**
 832       * Determines the padding modes
 833       *
 834       * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1);
 835       *
 836       * @param int $padding
 837       */
 838      public function withPadding($padding)
 839      {
 840          $masks = [
 841              self::ENCRYPTION_OAEP,
 842              self::ENCRYPTION_PKCS1,
 843              self::ENCRYPTION_NONE
 844          ];
 845          $encryptedCount = 0;
 846          $selected = 0;
 847          foreach ($masks as $mask) {
 848              if ($padding & $mask) {
 849                  $selected = $mask;
 850                  $encryptedCount++;
 851              }
 852          }
 853          if ($encryptedCount > 1) {
 854              throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected');
 855          }
 856          $encryptionPadding = $selected;
 857  
 858          $masks = [
 859              self::SIGNATURE_PSS,
 860              self::SIGNATURE_RELAXED_PKCS1,
 861              self::SIGNATURE_PKCS1
 862          ];
 863          $signatureCount = 0;
 864          $selected = 0;
 865          foreach ($masks as $mask) {
 866              if ($padding & $mask) {
 867                  $selected = $mask;
 868                  $signatureCount++;
 869              }
 870          }
 871          if ($signatureCount > 1) {
 872              throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected');
 873          }
 874          $signaturePadding = $selected;
 875  
 876          $new = clone $this;
 877          if ($encryptedCount) {
 878              $new->encryptionPadding = $encryptionPadding;
 879          }
 880          if ($signatureCount) {
 881              $new->signaturePadding = $signaturePadding;
 882          }
 883          return $new;
 884      }
 885  
 886      /**
 887       * Returns the padding currently being used
 888       *
 889       */
 890      public function getPadding()
 891      {
 892          return $this->signaturePadding | $this->encryptionPadding;
 893      }
 894  
 895      /**
 896       * Returns the current engine being used
 897       *
 898       * OpenSSL is only used in this class (and it's subclasses) for key generation
 899       * Even then it depends on the parameters you're using. It's not used for
 900       * multi-prime RSA nor is it used if the key length is outside of the range
 901       * supported by OpenSSL
 902       *
 903       * @see self::useInternalEngine()
 904       * @see self::useBestEngine()
 905       * @return string
 906       */
 907      public function getEngine()
 908      {
 909          if (!isset(self::$engines['PHP'])) {
 910              self::useBestEngine();
 911          }
 912          return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ?
 913              'OpenSSL' :
 914              'PHP';
 915      }
 916  
 917      /**
 918       * Enable RSA Blinding
 919       *
 920       */
 921      public static function enableBlinding()
 922      {
 923          static::$enableBlinding = true;
 924      }
 925  
 926      /**
 927       * Disable RSA Blinding
 928       *
 929       */
 930      public static function disableBlinding()
 931      {
 932          static::$enableBlinding = false;
 933      }
 934  }