setDerivationSalt()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 14
ccs 7
cts 7
cp 1
rs 10
cc 3
nc 2
nop 1
crap 3
1
<?php
2
3
/**
4
 * Abstraction for the slow iterative derivation algorithm objects.
5
 */
6
7
namespace CryptoManana\Core\Abstractions\MessageDigestion;
8
9
use CryptoManana\Core\Abstractions\MessageDigestion\AbstractPasswordBasedDerivationFunction as PasswordDerivation;
10
use CryptoManana\Core\Interfaces\MessageDigestion\DerivationSaltingInterface as DerivationSalting;
11
use CryptoManana\Core\Interfaces\MessageDigestion\DerivationDigestLengthInterface as DerivationDigestLength;
12
use CryptoManana\Core\Interfaces\MessageDigestion\DerivationIterationControlInterface as DerivationIterationControl;
13
use CryptoManana\Core\Interfaces\MessageDigestion\SecureVerificationInterface as DataVerification;
14
use CryptoManana\Core\Traits\MessageDigestion\DerivationSaltingTrait as DerivationSaltingCapabilities;
15
use CryptoManana\Core\Traits\MessageDigestion\DerivationDigestLengthTrait as DerivationDigestLengthCapabilities;
16
use CryptoManana\Core\Traits\MessageDigestion\DerivationIterationControlTrait as IterationControlCapabilities;
17
use CryptoManana\Core\Traits\MessageDigestion\SecureVerificationTrait as VerifyDataAndPasswords;
18
use CryptoManana\Core\StringBuilder as StringBuilder;
19
20
/**
21
 * Class AbstractIterativeSlowDerivation - The iterative derivation algorithm abstraction representation.
22
 *
23
 * @package CryptoManana\Core\Abstractions\MessageDigestion
24
 *
25
 * @mixin DerivationSaltingCapabilities
26
 * @mixin DerivationDigestLengthCapabilities
27
 * @mixin IterationControlCapabilities
28
 * @mixin VerifyDataAndPasswords
29
 */
30
abstract class AbstractIterativeSlowDerivation extends PasswordDerivation implements
31
    DerivationSalting,
32
    DerivationDigestLength,
33
    DerivationIterationControl,
34
    DataVerification
35
{
36
    /**
37
     * Derivation data salting capabilities.
38
     *
39
     * {@internal Reusable implementation of `DerivationSaltingInterface`. }}
40
     */
41
    use DerivationSaltingCapabilities;
42
43
    /**
44
     * Derivation control over the outputting digest length capabilities.
45
     *
46
     * {@internal Reusable implementation of `DerivationDigestLengthInterface`. }}
47
     */
48
    use DerivationDigestLengthCapabilities;
49
50
    /**
51
     * Derivation internal iterations control capabilities.
52
     *
53
     * {@internal Reusable implementation of `DerivationIterationControlInterface`. }}
54
     */
55
    use IterationControlCapabilities;
56
57
    /**
58
     * Secure password and data verification capabilities.
59
     *
60
     * {@internal Reusable implementation of `SecureVerificationInterface`. }}
61
     */
62
    use VerifyDataAndPasswords;
63
64
    /**
65
     * The derivation salt string property storage.
66
     *
67
     * @var string The derivation salting string value.
68
     */
69
    protected $derivationSalt = '';
70
71
    /**
72
     * The derivation output digest size in bytes length property storage.
73
     *
74
     * @var int The derivation output digest size in bytes length value.
75
     *
76
     * @note The default output size in bytes for this algorithm.
77
     */
78
    protected $outputLength = 0;
79
80
    /**
81
     * The derivation internal iteration count property storage.
82
     *
83
     * @var int The number of internal iterations to perform for the derivation.
84
     */
85
    protected $numberOfIterations = 1;
86
87
    /**
88
     * Password-based key derivation algorithm constructor.
89
     */
90 287
    public function __construct()
91
    {
92 287
        parent::__construct();
93
    }
94
95
    /**
96
     * Get debug information for the class instance.
97
     *
98
     * @return array Debug information.
99
     */
100 15
    public function __debugInfo()
101
    {
102 15
        return [
103 15
            'standard' => static::ALGORITHM_NAME,
104 15
            'type' => 'key stretching or password-based key derivation',
105 15
            'salt' => $this->salt,
106 15
            'mode' => $this->saltingMode,
107 15
            'derivation salt' => $this->derivationSalt,
108 15
            'digestion output length in bytes' => $this->outputLength,
109 15
            'number of internal iterations' => $this->numberOfIterations,
110 15
        ];
111
    }
112
113
    /**
114
     * Calculates a hash value for the given data.
115
     *
116
     * @param string $data The input string.
117
     *
118
     * @return string The digest.
119
     * @throws \Exception Validation errors.
120
     */
121 110
    public function hashData($data)
122
    {
123 110
        if (!is_string($data)) {
124 11
            throw new \InvalidArgumentException('The data for hashing must be a string or a binary string.');
125
        }
126
127 99
        $data = $this->addSaltString($data);
128
129 99
        $digest = hash_pbkdf2(
130 99
            static::ALGORITHM_NAME,
131 99
            $data,
132 99
            $this->derivationSalt,
133 99
            $this->numberOfIterations,
134 99
            $this->outputLength,
135 99
            true // The format here by default is `self::DIGEST_OUTPUT_RAW`
136 99
        );
137
138 99
        if ($this->digestFormat !== self::DIGEST_OUTPUT_RAW) {
139 99
            $digest = bin2hex($digest);
140
        }
141
142 99
        $digest = $this->changeOutputFormat($digest);
143
144 99
        return $digest;
145
    }
146
147
    /**
148
     * Setter for the derivation salt string property.
149
     *
150
     * @param string $derivationSalt The derivation salt string.
151
     *
152
     * @return $this The hash algorithm object.
153
     * @throws \Exception Validation errors.
154
     */
155 30
    public function setDerivationSalt($derivationSalt)
156
    {
157
        /**
158
         * {@internal An extra specification for the PBKDF2 digestion generation logic. }}
159
         */
160 30
        if (!is_string($derivationSalt) || StringBuilder::stringLength($derivationSalt) > PHP_INT_MAX - 4) {
161 15
            throw new \InvalidArgumentException(
162 15
                'The derivation salt must be of type string and be smaller than `PHP_INT_MAX - 4`.'
163 15
            );
164
        }
165
166 15
        $this->derivationSalt = $derivationSalt;
167
168 15
        return $this;
169
    }
170
}
171