Passed
Branch master (de8919)
by Tony Karavasilev (Тони
02:41
created

BlockOperationsTrait::setBlockOperationMode()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 29
ccs 12
cts 12
cp 1
rs 9.7666
cc 4
nc 3
nop 1
crap 4
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
     * Setter for the initialization vector (IV) string property.
28
     *
29
     * @param string $iv The initialization vector (IV) string.
30
     *
31
     * @return $this The encryption algorithm object.
32
     * @throws \Exception Validation errors.
33
     */
34 48
    public function setInitializationVector($iv)
35
    {
36 48
        if (!is_string($iv)) {
37 12
            throw new \InvalidArgumentException('The initialization vector must be a string or a binary string.');
38
        }
39
40
        /**
41
         * {@internal The encryption standard is 8-bit wise (don not use StringBuilder) and utilizes performance. }}
42
         */
43 36
        if (strlen($iv) > static::IV_SIZE) {
44 12
            $iv = hash_hkdf('sha256', $iv, static::IV_SIZE, 'CryptoMañana', '');
45 36
        } elseif (strlen($iv) < static::IV_SIZE) {
46 12
            $iv = str_pad($iv, static::IV_SIZE, "\x0", STR_PAD_RIGHT);
47
        }
48
49 36
        $this->iv = $iv;
50
51 36
        return $this;
52
    }
53
54
    /**
55
     * Getter for the initialization vector (IV) string property.
56
     *
57
     * @return string The initialization vector (IV) string.
58
     */
59 36
    public function getInitializationVector()
60
    {
61 36
        return $this->iv;
62
    }
63
64
    /**
65
     * Setter for the block encryption operation mode string property.
66
     *
67
     * @param string $mode The block operation mode string.
68
     *
69
     * @return $this The encryption algorithm object.
70
     * @throws \Exception Validation errors.
71
     */
72 60
    public function setBlockOperationMode($mode)
73
    {
74
        $validModes = [
75 60
            self::CBC_MODE,
76 60
            self::CFB_MODE,
77 60
            self::OFB_MODE,
78 60
            self::CTR_MODE,
79 60
            self::ECB_MODE
80
        ];
81
82 60
        if (!is_string($mode) || !in_array(strtoupper($mode), $validModes, true)) {
83 24
            throw new \InvalidArgumentException(
84 24
                'The mode of operation must be a string and be a standardized block mode name.'
85
            );
86
        }
87
88 36
        $newMethodName = static::ALGORITHM_NAME . '-' . (static::KEY_SIZE * 8) . '-' . $mode;
89
90
        // @codeCoverageIgnoreStart
91
        if (!in_array($newMethodName, openssl_get_cipher_methods(), true)) {
92
            throw new \RuntimeException(
93
                'The algorithm `' . $newMethodName . '`is not supported under the current system configuration.'
94
            );
95
        }
96
        // @codeCoverageIgnoreEnd
97
98 36
        $this->mode = strtoupper($mode);
99
100 36
        return $this;
101
    }
102
103
    /**
104
     * Getter for the block encryption operation mode string property.
105
     *
106
     * @return string The block operation mode string.
107
     */
108 36
    public function getBlockOperationMode()
109
    {
110 36
        return $this->mode;
111
    }
112
113
    /**
114
     * Setter for the final block padding operation property.
115
     *
116
     * @param int $padding The padding standard integer code value.
117
     *
118
     * @return $this The encryption algorithm object.
119
     * @throws \Exception Validation errors.
120
     */
121 48
    public function setPaddingStandard($padding)
122
    {
123 48
        $padding = filter_var(
124 48
            $padding,
125 48
            FILTER_VALIDATE_INT,
126
            [
127
                "options" => [
128 48
                    "min_range" => self::PKCS7_PADDING,
129 48
                    "max_range" => self::ZERO_PADDING,
130
                ],
131
            ]
132
        );
133
134 48
        if ($padding === false) {
135 12
            throw new \InvalidArgumentException(
136
                'The padding standard must must be a valid integer between ' .
137 12
                self::PKCS7_PADDING . ' and ' . self::ZERO_PADDING . '.'
138
            );
139
        }
140
141 36
        $this->padding = $padding;
142
143 36
        return $this;
144
    }
145
146
    /**
147
     * Getter for the final block padding operation property.
148
     *
149
     * @return string The padding standard integer code value.
150
     */
151 36
    public function getPaddingStandard()
152
    {
153 36
        return $this->padding;
154
    }
155
}
156