Completed
Branch master (95c3c5)
by
unknown
05:09
created

Encryption   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 6

Importance

Changes 0
Metric Value
wmc 4
lcom 0
cbo 6
dl 0
loc 71
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A encrypt() 0 6 1
A decrypt() 0 22 1
A encryptWithSaltAndIV() 0 16 2
1
<?php
2
3
namespace Blocktrail\SDK\V3Crypt;
4
5
use AESGCM\AESGCM;
6
use BitWasp\Buffertools\Buffer;
7
use BitWasp\Buffertools\BufferInterface;
8
use BitWasp\Buffertools\Buffertools;
9
use BitWasp\Buffertools\Parser;
10
11
class Encryption
12
{
13
    const DEFAULT_SALTLEN = 10;
14
    const TAGLEN_BITS = 128;
15
    const IVLEN_BYTES = 16;
16
17
    /**
18
     * @param BufferInterface $pt
19
     * @param BufferInterface $pw
20
     * @return BufferInterface
21
     */
22
    public static function encrypt(BufferInterface $pt, BufferInterface $pw) {
23
        $salt = new Buffer(random_bytes(self::DEFAULT_SALTLEN));
24
        $iv = new Buffer(random_bytes(self::IVLEN_BYTES));
25
        $iterations = KeyDerivation::DEFAULT_ITERATIONS;
26
        return self::encryptWithSaltAndIV($pt, $pw, $salt, $iv, $iterations);
27
    }
28
29
    /**
30
     * @param BufferInterface $ct
31
     * @param BufferInterface $pw
32
     * @return BufferInterface
33
     */
34
    public static function decrypt(BufferInterface $ct, BufferInterface $pw) {
35
        $parser = new Parser($ct);
36
        $sLB = $parser->readBytes(1);
37
        $salt = $parser->readBytes($sLB->getInt());
38
        $itB = $parser->readBytes(4);
39
        $header = new Buffer($sLB->getBinary() . $salt->getBinary() . $itB->getBinary());
40
41
        $iv = $parser->readBytes(16);
42
        $act = $parser->readBytes($ct->getSize() - $parser->getPosition());
43
        $tag = $act->slice(-16);
44
        $ct = $act->slice(0, -16);
45
46
        return new Buffer(
47
            AESGCM::decrypt(
48
                KeyDerivation::compute($pw, $salt, unpack('V', $itB->getBinary())[1])->getBinary(),
49
                $iv->getBinary(),
50
                $ct->getBinary(),
51
                $header->getBinary(),
52
                $tag->getBinary()
53
            )
54
        );
55
    }
56
57
    /**
58
     * @param BufferInterface $pt
59
     * @param BufferInterface $pw
60
     * @param BufferInterface $salt
61
     * @param BufferInterface $iv
62
     * @param int $iterations
63
     * @return BufferInterface
64
     */
65
    public static function encryptWithSaltAndIV(BufferInterface $pt, BufferInterface $pw, BufferInterface $salt, BufferInterface $iv, $iterations) {
66
        if ($iv->getSize() !== 16) {
67
            throw new \RuntimeException('IV must be exactly 16 bytes');
68
        }
69
70
        $header = new Buffer(pack('c', $salt->getSize()) . $salt->getBinary() . pack('V', $iterations));
71
72
        list ($ct, $tag) = AESGCM::encrypt(
73
            KeyDerivation::compute($pw, $salt, $iterations)->getBinary(),
74
            $iv->getBinary(),
75
            $pt->getBinary(),
76
            $header->getBinary()
77
        );
78
79
        return Buffertools::concat($header, new Buffer($iv->getBinary() . $ct . $tag));
80
    }
81
}
82