Passed
Push — master ( 9c982a...ad2785 )
by Tony Karavasilev (Тони
19:53
created

BlockOperationsTrait::validateBlockModeSupport()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
/**
4
 * Trait implementation of the block cipher capabilities and actions for symmetric encryption algorithms.
5
 */
6
7
namespace CryptoManana\Core\Traits\MessageEncryption;
8
9
use \CryptoManana\Core\Interfaces\MessageEncryption\BlockOperationsInterface as BlockOperationsSpecification;
10
11
/**
12
 * Trait BlockOperationsTrait - Reusable implementation of `BlockOperationsInterface`.
13
 *
14
 * @see \CryptoManana\Core\Interfaces\MessageDigestion\BlockOperationsInterface The abstract specification.
15
 *
16
 * @package CryptoManana\Core\Traits\MessageEncryption
17
 *
18
 * @property string $iv The initialization vector (IV) string property storage.
19
 * @property string $mode The block encryption operation mode string property.
20
 * @property int $padding The final block padding operation property.
21
 *
22
 * @mixin BlockOperationsSpecification
23
 */
24
trait BlockOperationsTrait
25
{
26
    /**
27
     * List of valid block operation modes.
28
     *
29
     * @var array Block mode codes.
30
     */
31
    protected static $validBlockModes = [
32
        self::CBC_MODE,
33
        self::CFB_MODE,
34
        self::OFB_MODE,
35
        self::CTR_MODE,
36
        self::ECB_MODE
37
    ];
38
39
    /**
40
     * Internal method for the validation of the system support of the given block operation mode.
41
     *
42
     * @param string $mode The block mode name.
43
     *
44
     * @throws \Exception Validation errors.
45
     *
46
     * @codeCoverageIgnore
47
     */
48
    protected function validateBlockModeSupport($mode)
49
    {
50
        $methodName = static::ALGORITHM_NAME . '-' . (static::KEY_SIZE * 8) . '-' . strtoupper($mode);
2 ignored issues
show
Bug introduced by
The constant CryptoManana\Core\Traits...nsTrait::ALGORITHM_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The constant CryptoManana\Core\Traits...erationsTrait::KEY_SIZE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
51
52
        if (!in_array($methodName, openssl_get_cipher_methods(), true)) {
53
            throw new \RuntimeException(
54
                'The algorithm `' . $methodName . '`is not supported under the current system configuration.'
55
            );
56
        }
57
    }
58
59
    /**
60
     * Setter for the initialization vector (IV) string property.
61
     *
62
     * @param string $iv The initialization vector (IV) string.
63
     *
64
     * @return $this The symmetric encryption algorithm object.
65
     * @throws \Exception Validation errors.
66
     */
67 96
    public function setInitializationVector($iv)
68
    {
69 96
        if (!is_string($iv)) {
70 14
            throw new \InvalidArgumentException('The initialization vector must be a string or a binary string.');
71
        }
72
73
        /**
74
         * {@internal The encryption standard is 8-bit wise (don not use StringBuilder) and utilizes performance. }}
75
         */
76 82
        if (strlen($iv) > static::IV_SIZE) {
77 52
            $iv = hash_hkdf('sha256', $iv, static::IV_SIZE, 'CryptoMañana', '');
78 66
        } elseif (strlen($iv) < static::IV_SIZE) {
79 14
            $iv = str_pad($iv, static::IV_SIZE, "\x0", STR_PAD_RIGHT);
80
        }
81
82 82
        $this->iv = $iv;
83
84 82
        return $this;
85
    }
86
87
    /**
88
     * Getter for the initialization vector (IV) string property.
89
     *
90
     * @return string The initialization vector (IV) string.
91
     */
92 98
    public function getInitializationVector()
93
    {
94 98
        return $this->iv;
95
    }
96
97
    /**
98
     * Setter for the block encryption operation mode string property.
99
     *
100
     * @param string $mode The block operation mode string.
101
     *
102
     * @return $this The symmetric encryption algorithm object.
103
     * @throws \Exception Validation errors.
104
     */
105 70
    public function setBlockOperationMode($mode)
106
    {
107 70
        if (!is_string($mode) || !in_array(strtoupper($mode), static::$validBlockModes, true)) {
1 ignored issue
show
introduced by
The condition is_string($mode) is always true.
Loading history...
108 28
            throw new \InvalidArgumentException(
109 28
                'The mode of operation must be a string and be a standardized block mode name.'
110
            );
111
        }
112
113 42
        $this->validateBlockModeSupport($mode);
114
115 42
        $this->mode = strtoupper($mode);
116
117 42
        return $this;
118
    }
119
120
    /**
121
     * Getter for the block encryption operation mode string property.
122
     *
123
     * @return string The block operation mode string.
124
     */
125 42
    public function getBlockOperationMode()
126
    {
127 42
        return $this->mode;
128
    }
129
130
    /**
131
     * Setter for the final block padding operation property.
132
     *
133
     * @param int $padding The padding standard integer code value.
134
     *
135
     * @return $this The symmetric encryption algorithm object.
136
     * @throws \Exception Validation errors.
137
     */
138 56
    public function setPaddingStandard($padding)
139
    {
140 56
        $padding = filter_var(
141 56
            $padding,
142 56
            FILTER_VALIDATE_INT,
143
            [
144
                "options" => [
145 56
                    "min_range" => self::PKCS7_PADDING,
146 56
                    "max_range" => self::ZERO_PADDING,
147
                ],
148
            ]
149
        );
150
151 56
        if ($padding === false) {
152 14
            throw new \InvalidArgumentException(
153
                'The padding standard must be a valid integer between ' .
154 14
                self::PKCS7_PADDING . ' and ' . self::ZERO_PADDING . '.'
155
            );
156
        }
157
158 42
        $this->padding = $padding;
159
160 42
        return $this;
161
    }
162
163
    /**
164
     * Getter for the final block padding operation property.
165
     *
166
     * @return string The padding standard integer code value.
167
     */
168 42
    public function getPaddingStandard()
169
    {
170 42
        return $this->padding;
171
    }
172
}
173