Completed
Push — master ( 022625...2b82d4 )
by Florent
05:58
created

AESCBCHS::decryptContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 1
eloc 6
nc 1
nop 6
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose\Algorithm\ContentEncryption;
13
14
use Assert\Assertion;
15
use Jose\Algorithm\ContentEncryptionAlgorithmInterface;
16
17
abstract class AESCBCHS implements ContentEncryptionAlgorithmInterface
18
{
19
    /**
20
     * {@inheritdoc}
21
     */
22
    public function encryptContent($data, $cek, $iv, $aad, $encoded_protected_header, &$tag)
23
    {
24
        $k = mb_substr($cek, mb_strlen($cek, '8bit') / 2, null, '8bit');
25
26
        $cyphertext = openssl_encrypt($data, $this->getMode($k), $k, OPENSSL_RAW_DATA, $iv);
27
28
        $tag = $this->calculateAuthenticationTag($cyphertext, $cek, $iv, $aad, $encoded_protected_header);
29
30
        return $cyphertext;
31
    }
32
33
    /**
34
     * @param string      $data
35
     * @param string      $cek
36
     * @param string      $iv
37
     * @param string      $aad
38
     * @param string      $encoded_protected_header
39
     * @param string|null $aad
40
     * @param string      $tag
41
     *
42
     * @return string
43
     */
44
    public function decryptContent($data, $cek, $iv, $aad, $encoded_protected_header, $tag)
45
    {
46
        Assertion::true(
47
            $this->isTagValid($data, $cek, $iv, $aad, $encoded_protected_header, $tag),
48
            'Unable to verify the tag.'
49
        );
50
51
        $k = mb_substr($cek, mb_strlen($cek, '8bit') / 2, null, '8bit');
52
53
        return openssl_decrypt($data, self::getMode($k), $k, OPENSSL_RAW_DATA, $iv);
54
    }
55
56
    /**
57
     * @param $encrypted_data
58
     * @param $cek
59
     * @param $iv
60
     * @param $aad
61
     * @param string $encoded_header
62
     *
63
     * @return string
64
     */
65
    protected function calculateAuthenticationTag($encrypted_data, $cek, $iv, $aad, $encoded_header)
66
    {
67
        $calculated_aad = $encoded_header;
68
        if (null !== $aad) {
69
            $calculated_aad .= '.'.$aad;
70
        }
71
        $mac_key = mb_substr($cek, 0, mb_strlen($cek, '8bit') / 2, '8bit');
72
        $auth_data_length = mb_strlen($encoded_header, '8bit');
73
74
        $secured_input = implode('', [
75
            $calculated_aad,
76
            $iv,
77
            $encrypted_data,
78
            pack('N2', ($auth_data_length / 2147483647) * 8, ($auth_data_length % 2147483647) * 8), // str_pad(dechex($auth_data_length), 4, "0", STR_PAD_LEFT)
79
        ]);
80
        $hash = hash_hmac($this->getHashAlgorithm(), $secured_input, $mac_key, true);
81
82
        return  mb_substr($hash, 0, mb_strlen($hash, '8bit') / 2, '8bit');
83
    }
84
85
    /**
86
     * @param string      $authentication_tag
87
     * @param string      $encoded_header
88
     * @param string      $encrypted_data
89
     * @param string      $cek
90
     * @param string      $iv
91
     * @param string|null $aad
92
     *
93
     * @return bool
94
     */
95
    protected function isTagValid($encrypted_data, $cek, $iv, $aad, $encoded_header, $authentication_tag)
96
    {
97
        return $authentication_tag === $this->calculateAuthenticationTag($encrypted_data, $cek, $iv, $aad, $encoded_header);
98
    }
99
100
    /**
101
     * @return string
102
     */
103
    abstract protected function getHashAlgorithm();
104
105
    /**
106
     * @return int
107
     */
108
    public function getIVSize()
109
    {
110
        return 128;
111
    }
112
113
    /**
114
     * @param string $k
115
     *
116
     * @return string
117
     */
118
    private function getMode($k)
119
    {
120
        return 'aes-'.(8 *  mb_strlen($k, '8bit')).'-cbc';
121
    }
122
}
123