Subversion Repositories oidplus

Rev

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