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 = 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 = 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 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 Math\BigInteger
198      */
199     protected $modulus;
200 
201     /**
202      * Modulus length
203      *
204      * @var Math\BigInteger
205      */
206     protected $k;
207 
208     /**
209      * Exponent (ie. e or d)
210      *
211      * @var 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 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 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|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 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         // 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         // 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 }
935