Subversion Repositories oidplus

Rev

Rev 874 | Rev 1101 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
827 daniel-mar 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
    /**
1042 daniel-mar 253
     * Public Exponent
254
     *
255
     * @var \phpseclib3\Math\BigInteger
256
     */
257
    protected $publicExponent;
258
 
259
    /**
827 daniel-mar 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
     *
1042 daniel-mar 300
     * @return RSA\PrivateKey
827 daniel-mar 301
     * @param int $bits
302
     */
303
    public static function createKey($bits = 2048)
304
    {
305
        self::initialize_static_variables();
306
 
307
        $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be
308
        if ($regSize > self::$smallestPrime) {
309
            $num_primes = floor($bits / self::$smallestPrime);
310
            $regSize = self::$smallestPrime;
311
        } else {
312
            $num_primes = 2;
313
        }
314
 
315
        if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) {
316
            if (!isset(self::$engines['PHP'])) {
317
                self::useBestEngine();
318
            }
319
 
320
            // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
321
            if (self::$engines['OpenSSL']) {
322
                $config = [];
323
                if (self::$configFile) {
324
                    $config['config'] = self::$configFile;
325
                }
326
                $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config);
327
                openssl_pkey_export($rsa, $privatekeystr, null, $config);
328
 
329
                // clear the buffer of error strings stemming from a minimalistic openssl.cnf
330
                while (openssl_error_string() !== false) {
331
                }
332
 
333
                return RSA::load($privatekeystr);
334
            }
335
        }
336
 
337
        static $e;
338
        if (!isset($e)) {
339
            $e = new BigInteger(self::$defaultExponent);
340
        }
341
 
342
        $n = clone self::$one;
343
        $exponents = $coefficients = $primes = [];
344
        $lcm = [
345
            'top' => clone self::$one,
346
            'bottom' => false
347
        ];
348
 
349
        do {
350
            for ($i = 1; $i <= $num_primes; $i++) {
351
                if ($i != $num_primes) {
352
                    $primes[$i] = BigInteger::randomPrime($regSize);
353
                } else {
354
                    extract(BigInteger::minMaxBits($bits));
355
                    /** @var BigInteger $min
356
                     *  @var BigInteger $max
357
                     */
358
                    list($min) = $min->divide($n);
359
                    $min = $min->add(self::$one);
360
                    list($max) = $max->divide($n);
361
                    $primes[$i] = BigInteger::randomRangePrime($min, $max);
362
                }
363
 
364
                // the first coefficient is calculated differently from the rest
365
                // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
366
                if ($i > 2) {
367
                    $coefficients[$i] = $n->modInverse($primes[$i]);
368
                }
369
 
370
                $n = $n->multiply($primes[$i]);
371
 
372
                $temp = $primes[$i]->subtract(self::$one);
373
 
374
                // textbook RSA implementations use Euler's totient function instead of the least common multiple.
375
                // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
376
                $lcm['top'] = $lcm['top']->multiply($temp);
377
                $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
378
            }
379
 
380
            list($temp) = $lcm['top']->divide($lcm['bottom']);
381
            $gcd = $temp->gcd($e);
382
            $i0 = 1;
383
        } while (!$gcd->equals(self::$one));
384
 
385
        $coefficients[2] = $primes[2]->modInverse($primes[1]);
386
 
387
        $d = $e->modInverse($temp);
388
 
389
        foreach ($primes as $i => $prime) {
390
            $temp = $prime->subtract(self::$one);
391
            $exponents[$i] = $e->modInverse($temp);
392
        }
393
 
394
        // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
395
        // RSAPrivateKey ::= SEQUENCE {
396
        //     version           Version,
397
        //     modulus           INTEGER,  -- n
398
        //     publicExponent    INTEGER,  -- e
399
        //     privateExponent   INTEGER,  -- d
400
        //     prime1            INTEGER,  -- p
401
        //     prime2            INTEGER,  -- q
402
        //     exponent1         INTEGER,  -- d mod (p-1)
403
        //     exponent2         INTEGER,  -- d mod (q-1)
404
        //     coefficient       INTEGER,  -- (inverse of q) mod p
405
        //     otherPrimeInfos   OtherPrimeInfos OPTIONAL
406
        // }
407
        $privatekey = new PrivateKey();
408
        $privatekey->modulus = $n;
409
        $privatekey->k = $bits >> 3;
410
        $privatekey->publicExponent = $e;
411
        $privatekey->exponent = $d;
412
        $privatekey->primes = $primes;
413
        $privatekey->exponents = $exponents;
414
        $privatekey->coefficients = $coefficients;
415
 
416
        /*
417
        $publickey = new PublicKey;
418
        $publickey->modulus = $n;
419
        $publickey->k = $bits >> 3;
420
        $publickey->exponent = $e;
421
        $publickey->publicExponent = $e;
422
        $publickey->isPublic = true;
423
        */
424
 
425
        return $privatekey;
426
    }
427
 
428
    /**
429
     * OnLoad Handler
430
     *
431
     * @return bool
432
     */
1042 daniel-mar 433
    protected static function onLoad(array $components)
827 daniel-mar 434
    {
435
        $key = $components['isPublicKey'] ?
436
            new PublicKey() :
437
            new PrivateKey();
438
 
439
        $key->modulus = $components['modulus'];
440
        $key->publicExponent = $components['publicExponent'];
441
        $key->k = $key->modulus->getLengthInBytes();
442
 
443
        if ($components['isPublicKey'] || !isset($components['privateExponent'])) {
444
            $key->exponent = $key->publicExponent;
445
        } else {
446
            $key->privateExponent = $components['privateExponent'];
447
            $key->exponent = $key->privateExponent;
448
            $key->primes = $components['primes'];
449
            $key->exponents = $components['exponents'];
450
            $key->coefficients = $components['coefficients'];
451
        }
452
 
453
        if ($components['format'] == PSS::class) {
454
            // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is
455
            // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib
456
            // uses PSS padding by default. it assumes the more secure method by default and altho it provides
457
            // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent
458
            // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that
459
            // not only does it defaults to the most secure methods - it doesn't even let you choose less
460
            // secure methods
461
            //$key = $key->withPadding(self::SIGNATURE_PSS);
462
            if (isset($components['hash'])) {
463
                $key = $key->withHash($components['hash']);
464
            }
465
            if (isset($components['MGFHash'])) {
466
                $key = $key->withMGFHash($components['MGFHash']);
467
            }
468
            if (isset($components['saltLength'])) {
469
                $key = $key->withSaltLength($components['saltLength']);
470
            }
471
        }
472
 
473
        return $key;
474
    }
475
 
476
    /**
477
     * Initialize static variables
478
     */
479
    protected static function initialize_static_variables()
480
    {
481
        if (!isset(self::$configFile)) {
482
            self::$configFile = dirname(__FILE__) . '/../openssl.cnf';
483
        }
484
 
485
        parent::initialize_static_variables();
486
    }
487
 
488
    /**
489
     * Constructor
490
     *
491
     * PublicKey and PrivateKey objects can only be created from abstract RSA class
492
     */
493
    protected function __construct()
494
    {
495
        parent::__construct();
496
 
497
        $this->hLen = $this->hash->getLengthInBytes();
498
        $this->mgfHash = new Hash('sha256');
499
        $this->mgfHLen = $this->mgfHash->getLengthInBytes();
500
    }
501
 
502
    /**
503
     * Integer-to-Octet-String primitive
504
     *
505
     * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
506
     *
507
     * @param bool|\phpseclib3\Math\BigInteger $x
508
     * @param int $xLen
509
     * @return bool|string
510
     */
511
    protected function i2osp($x, $xLen)
512
    {
513
        if ($x === false) {
514
            return false;
515
        }
516
        $x = $x->toBytes();
517
        if (strlen($x) > $xLen) {
518
            throw new \OutOfRangeException('Resultant string length out of range');
519
        }
520
        return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
521
    }
522
 
523
    /**
524
     * Octet-String-to-Integer primitive
525
     *
526
     * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
527
     *
528
     * @param string $x
529
     * @return \phpseclib3\Math\BigInteger
530
     */
531
    protected function os2ip($x)
532
    {
533
        return new BigInteger($x, 256);
534
    }
535
 
536
    /**
537
     * EMSA-PKCS1-V1_5-ENCODE
538
     *
539
     * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
540
     *
541
     * @param string $m
542
     * @param int $emLen
543
     * @throws \LengthException if the intended encoded message length is too short
544
     * @return string
545
     */
546
    protected function emsa_pkcs1_v1_5_encode($m, $emLen)
547
    {
548
        $h = $this->hash->hash($m);
549
 
550
        // see http://tools.ietf.org/html/rfc3447#page-43
551
        switch ($this->hash->getHash()) {
552
            case 'md2':
553
                $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10";
554
                break;
555
            case 'md5':
556
                $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
557
                break;
558
            case 'sha1':
559
                $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14";
560
                break;
561
            case 'sha256':
562
                $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
563
                break;
564
            case 'sha384':
565
                $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30";
566
                break;
567
            case 'sha512':
568
                $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40";
569
                break;
570
            // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
571
            case 'sha224':
572
                $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c";
573
                break;
574
            case 'sha512/224':
575
                $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c";
576
                break;
577
            case 'sha512/256':
578
                $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20";
579
        }
580
        $t .= $h;
581
        $tLen = strlen($t);
582
 
583
        if ($emLen < $tLen + 11) {
584
            throw new \LengthException('Intended encoded message length too short');
585
        }
586
 
587
        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
588
 
589
        $em = "\0\1$ps\0$t";
590
 
591
        return $em;
592
    }
593
 
594
    /**
595
     * EMSA-PKCS1-V1_5-ENCODE (without NULL)
596
     *
597
     * Quoting https://tools.ietf.org/html/rfc8017#page-65,
598
     *
599
     * "The parameters field associated with id-sha1, id-sha224, id-sha256,
600
     *  id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
601
     *  generally be omitted, but if present, it shall have a value of type
602
     *  NULL"
603
     *
604
     * @param string $m
605
     * @param int $emLen
606
     * @return string
607
     */
608
    protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
609
    {
610
        $h = $this->hash->hash($m);
611
 
612
        // see http://tools.ietf.org/html/rfc3447#page-43
613
        switch ($this->hash->getHash()) {
614
            case 'sha1':
615
                $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14";
616
                break;
617
            case 'sha256':
618
                $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20";
619
                break;
620
            case 'sha384':
621
                $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30";
622
                break;
623
            case 'sha512':
624
                $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40";
625
                break;
626
            // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
627
            case 'sha224':
628
                $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c";
629
                break;
630
            case 'sha512/224':
631
                $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c";
632
                break;
633
            case 'sha512/256':
634
                $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20";
635
                break;
636
            default:
637
                throw new UnsupportedAlgorithmException('md2 and md5 require NULLs');
638
        }
639
        $t .= $h;
640
        $tLen = strlen($t);
641
 
642
        if ($emLen < $tLen + 11) {
643
            throw new \LengthException('Intended encoded message length too short');
644
        }
645
 
646
        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
647
 
648
        $em = "\0\1$ps\0$t";
649
 
650
        return $em;
651
    }
652
 
653
    /**
654
     * MGF1
655
     *
656
     * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
657
     *
658
     * @param string $mgfSeed
659
     * @param int $maskLen
660
     * @return string
661
     */
662
    protected function mgf1($mgfSeed, $maskLen)
663
    {
664
        // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
665
 
666
        $t = '';
667
        $count = ceil($maskLen / $this->mgfHLen);
668
        for ($i = 0; $i < $count; $i++) {
669
            $c = pack('N', $i);
670
            $t .= $this->mgfHash->hash($mgfSeed . $c);
671
        }
672
 
673
        return substr($t, 0, $maskLen);
674
    }
675
 
676
    /**
677
     * Returns the key size
678
     *
679
     * More specifically, this returns the size of the modulo in bits.
680
     *
681
     * @return int
682
     */
683
    public function getLength()
684
    {
685
        return !isset($this->modulus) ? 0 : $this->modulus->getLength();
686
    }
687
 
688
    /**
689
     * Determines which hashing function should be used
690
     *
691
     * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and
692
     * decryption.
693
     *
694
     * @param string $hash
695
     */
696
    public function withHash($hash)
697
    {
698
        $new = clone $this;
699
 
700
        // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
701
        switch (strtolower($hash)) {
702
            case 'md2':
703
            case 'md5':
704
            case 'sha1':
705
            case 'sha256':
706
            case 'sha384':
707
            case 'sha512':
708
            case 'sha224':
709
            case 'sha512/224':
710
            case 'sha512/256':
711
                $new->hash = new Hash($hash);
712
                break;
713
            default:
714
                throw new UnsupportedAlgorithmException(
715
                    'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
716
                );
717
        }
718
        $new->hLen = $new->hash->getLengthInBytes();
719
 
720
        return $new;
721
    }
722
 
723
    /**
724
     * Determines which hashing function should be used for the mask generation function
725
     *
726
     * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's
727
     * best if Hash and MGFHash are set to the same thing this is not a requirement.
728
     *
729
     * @param string $hash
730
     */
731
    public function withMGFHash($hash)
732
    {
733
        $new = clone $this;
734
 
735
        // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
736
        switch (strtolower($hash)) {
737
            case 'md2':
738
            case 'md5':
739
            case 'sha1':
740
            case 'sha256':
741
            case 'sha384':
742
            case 'sha512':
743
            case 'sha224':
744
            case 'sha512/224':
745
            case 'sha512/256':
746
                $new->mgfHash = new Hash($hash);
747
                break;
748
            default:
749
                throw new UnsupportedAlgorithmException(
750
                    'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
751
                );
752
        }
753
        $new->mgfHLen = $new->mgfHash->getLengthInBytes();
754
 
755
        return $new;
756
    }
757
 
758
    /**
759
     * Returns the MGF hash algorithm currently being used
760
     *
761
     */
762
    public function getMGFHash()
763
    {
764
        return clone $this->mgfHash;
765
    }
766
 
767
    /**
768
     * Determines the salt length
769
     *
770
     * Used by RSA::PADDING_PSS
771
     *
772
     * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
773
     *
774
     *    Typical salt lengths in octets are hLen (the length of the output
775
     *    of the hash function Hash) and 0.
776
     *
777
     * @param int $sLen
778
     */
779
    public function withSaltLength($sLen)
780
    {
781
        $new = clone $this;
782
        $new->sLen = $sLen;
783
        return $new;
784
    }
785
 
786
    /**
787
     * Returns the salt length currently being used
788
     *
789
     */
790
    public function getSaltLength()
791
    {
792
        return $this->sLen !== null ? $this->sLen : $this->hLen;
793
    }
794
 
795
    /**
796
     * Determines the label
797
     *
798
     * Used by RSA::PADDING_OAEP
799
     *
800
     * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
801
     *
802
     *    Both the encryption and the decryption operations of RSAES-OAEP take
803
     *    the value of a label L as input.  In this version of PKCS #1, L is
804
     *    the empty string; other uses of the label are outside the scope of
805
     *    this document.
806
     *
807
     * @param string $label
808
     */
809
    public function withLabel($label)
810
    {
811
        $new = clone $this;
812
        $new->label = $label;
813
        return $new;
814
    }
815
 
816
    /**
817
     * Returns the label currently being used
818
     *
819
     */
820
    public function getLabel()
821
    {
822
        return $this->label;
823
    }
824
 
825
    /**
826
     * Determines the padding modes
827
     *
828
     * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1);
829
     *
830
     * @param int $padding
831
     */
832
    public function withPadding($padding)
833
    {
834
        $masks = [
835
            self::ENCRYPTION_OAEP,
836
            self::ENCRYPTION_PKCS1,
837
            self::ENCRYPTION_NONE
838
        ];
839
        $numSelected = 0;
840
        $selected = 0;
841
        foreach ($masks as $mask) {
842
            if ($padding & $mask) {
843
                $selected = $mask;
844
                $numSelected++;
845
            }
846
        }
847
        if ($numSelected > 1) {
848
            throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected');
849
        }
850
        $encryptionPadding = $selected;
851
 
852
        $masks = [
853
            self::SIGNATURE_PSS,
854
            self::SIGNATURE_RELAXED_PKCS1,
855
            self::SIGNATURE_PKCS1
856
        ];
857
        $numSelected = 0;
858
        $selected = 0;
859
        foreach ($masks as $mask) {
860
            if ($padding & $mask) {
861
                $selected = $mask;
862
                $numSelected++;
863
            }
864
        }
865
        if ($numSelected > 1) {
866
            throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected');
867
        }
868
        $signaturePadding = $selected;
869
 
870
        $new = clone $this;
871
        $new->encryptionPadding = $encryptionPadding;
872
        $new->signaturePadding = $signaturePadding;
873
        return $new;
874
    }
875
 
876
    /**
877
     * Returns the padding currently being used
878
     *
879
     */
880
    public function getPadding()
881
    {
882
        return $this->signaturePadding | $this->encryptionPadding;
883
    }
884
 
885
    /**
886
     * Returns the current engine being used
887
     *
888
     * OpenSSL is only used in this class (and it's subclasses) for key generation
889
     * Even then it depends on the parameters you're using. It's not used for
890
     * multi-prime RSA nor is it used if the key length is outside of the range
891
     * supported by OpenSSL
892
     *
893
     * @see self::useInternalEngine()
894
     * @see self::useBestEngine()
895
     * @return string
896
     */
897
    public function getEngine()
898
    {
899
        if (!isset(self::$engines['PHP'])) {
900
            self::useBestEngine();
901
        }
902
        return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ?
903
            'OpenSSL' :
904
            'PHP';
905
    }
906
 
907
    /**
908
     * Enable RSA Blinding
909
     *
910
     */
911
    public static function enableBlinding()
912
    {
913
        static::$enableBlinding = true;
914
    }
915
 
916
    /**
917
     * Disable RSA Blinding
918
     *
919
     */
920
    public static function disableBlinding()
921
    {
922
        static::$enableBlinding = false;
923
    }
924
}