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