Completed
Push — master ( 3e104b...182480 )
by Florent
02:59
created

AESCBCHS::getHashAlgorithm()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 1
nc 1
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 Jose\Algorithm\ContentEncryptionAlgorithmInterface;
15
16
/**
17
 *
18
 */
19
abstract class AESCBCHS implements ContentEncryptionAlgorithmInterface
20
{
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function encryptContent($data, $cek, $iv, $aad, $encoded_protected_header, &$tag)
25
    {
26
        $k = substr($cek, strlen($cek) / 2);
27
28
        $cyphertext = openssl_encrypt($data, $this->getMode($k), $k, OPENSSL_RAW_DATA, $iv);
29
30
        $tag = $this->calculateAuthenticationTag($cyphertext, $cek, $iv, $aad, $encoded_protected_header);
31
32
        return $cyphertext;
33
    }
34
35
    /**
36
     * @param string      $data
37
     * @param string      $cek
38
     * @param string      $iv
39
     * @param string      $aad
40
     * @param string      $encoded_protected_header
41
     * @param string|null $aad
42
     * @param string      $tag
43
     *
44
     * @return string
45
     */
46
    public function decryptContent($data, $cek, $iv, $aad, $encoded_protected_header, $tag)
47
    {
48
        if (false === $this->checkAuthenticationTag($data, $cek, $iv, $aad, $encoded_protected_header, $tag)) {
49
            return;
50
        }
51
52
        $k = substr($cek, strlen($cek) / 2);
53
54
        return openssl_decrypt($data, self::getMode($k), $k, OPENSSL_RAW_DATA, $iv);
55
    }
56
57
    /**
58
     * @param $encrypted_data
59
     * @param $cek
60
     * @param $iv
61
     * @param $aad
62
     * @param string $encoded_header
63
     *
64
     * @return string
65
     */
66
    protected function calculateAuthenticationTag($encrypted_data, $cek, $iv, $aad, $encoded_header)
67
    {
68
        $calculated_aad = $encoded_header;
69
        if (null !== $aad) {
70
            $calculated_aad .= '.'.$aad;
71
        }
72
        $mac_key = substr($cek, 0, strlen($cek) / 2);
73
        $auth_data_length = strlen($encoded_header);
74
75
        $secured_input = implode('', [
76
            $calculated_aad,
77
            $iv,
78
            $encrypted_data,
79
            pack('N2', ($auth_data_length / 2147483647) * 8, ($auth_data_length % 2147483647) * 8), // str_pad(dechex($auth_data_length), 4, "0", STR_PAD_LEFT)
80
        ]);
81
        $hash = hash_hmac($this->getHashAlgorithm(), $secured_input, $mac_key, true);
82
83
        return  substr($hash, 0, strlen($hash) / 2);
84
    }
85
86
    /**
87
     * @param string      $authentication_tag
88
     * @param string      $encoded_header
89
     * @param string      $encrypted_data
90
     * @param string      $cek
91
     * @param string      $iv
92
     * @param string|null $aad
93
     *
94
     * @return bool
95
     */
96
    protected function checkAuthenticationTag($encrypted_data, $cek, $iv, $aad, $encoded_header, $authentication_tag)
97
    {
98
        return $authentication_tag === $this->calculateAuthenticationTag($encrypted_data, $cek, $iv, $aad, $encoded_header);
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    abstract protected function getHashAlgorithm();
105
106
    /**
107
     * @return int
108
     */
109
    public function getIVSize()
110
    {
111
        return 128;
112
    }
113
114
    /**
115
     * @param string $k
116
     *
117
     * @return string
118
     */
119
    private function getMode($k)
120
    {
121
        return 'aes-'.(8 *  strlen($k)).'-cbc';
122
    }
123
}
124