HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/magento.bikenow.co/vendor/laminas/laminas-crypt/src/FileCipher.php
<?php

/**
 * @see       https://github.com/laminas/laminas-crypt for the canonical source repository
 * @copyright https://github.com/laminas/laminas-crypt/blob/master/COPYRIGHT.md
 * @license   https://github.com/laminas/laminas-crypt/blob/master/LICENSE.md New BSD License
 */

namespace Laminas\Crypt;

use Laminas\Crypt\Key\Derivation\Pbkdf2;
use Laminas\Crypt\Symmetric\Mcrypt;
use Laminas\Crypt\Symmetric\SymmetricInterface;
use Laminas\Math\Rand;

/**
 * Encrypt/decrypt a file using a symmetric cipher in CBC mode
 * then authenticate using HMAC
 */
class FileCipher
{
    const BUFFER_SIZE = 1048576; // 16 * 65536 bytes = 1 Mb

    /**
     * Hash algorithm for Pbkdf2
     *
     * @var string
     */
    protected $pbkdf2Hash = 'sha256';

    /**
     * Hash algorithm for HMAC
     *
     * @var string
     */
    protected $hash = 'sha256';

    /**
     * Number of iterations for Pbkdf2
     *
     * @var int
     */
    protected $keyIteration = 10000;

    /**
     * Key
     *
     * @var string
     */
    protected $key;

    /**
     * Cipher
     *
     * @var SymmetricInterface
     */
    protected $cipher;

    /**
     * Constructor
     *
     * @param SymmetricInterface $cipher
     */
    public function __construct()
    {
        $this->cipher = new Mcrypt;
    }

    /**
     * Set the cipher object
     *
     * @param SymmetricInterface $cipher
     */
    public function setCipher(SymmetricInterface $cipher)
    {
        $this->cipher = $cipher;
    }

    /**
     * Get the cipher object
     *
     * @return SymmetricInterface
     */
    public function getCipher()
    {
        return $this->cipher;
    }

    /**
     * Set the number of iterations for Pbkdf2
     *
     * @param  int  $num
     */
    public function setKeyIteration($num)
    {
        $this->keyIteration = (int) $num;
    }

    /**
     * Get the number of iterations for Pbkdf2
     *
     * @return int
     */
    public function getKeyIteration()
    {
        return $this->keyIteration;
    }

    /**
     * Set the encryption/decryption key
     *
     * @param  string                             $key
     * @throws Exception\InvalidArgumentException
     */
    public function setKey($key)
    {
        if (empty($key)) {
            throw new Exception\InvalidArgumentException('The key cannot be empty');
        }
        $this->key = (string) $key;
    }

    /**
     * Get the key
     *
     * @return string|null
     */
    public function getKey()
    {
        return $this->key;
    }

    /**
     * Set algorithm of the symmetric cipher
     *
     * @param  string                             $algo
     */
    public function setCipherAlgorithm($algo)
    {
        $this->cipher->setAlgorithm($algo);
    }

    /**
     * Get the cipher algorithm
     *
     * @return string|bool
     */
    public function getCipherAlgorithm()
    {
        return $this->cipher->getAlgorithm();
    }

    /**
     * Get the supported algorithms of the symmetric cipher
     *
     * @return array
     */
    public function getCipherSupportedAlgorithms()
    {
        return $this->cipher->getSupportedAlgorithms();
    }

    /**
     * Set the hash algorithm for HMAC authentication
     *
     * @param  string                             $hash
     * @throws Exception\InvalidArgumentException
     */
    public function setHashAlgorithm($hash)
    {
        if (!Hash::isSupported($hash)) {
            throw new Exception\InvalidArgumentException(
                "The specified hash algorithm '{$hash}' is not supported by Laminas\Crypt\Hash"
            );
        }
        $this->hash = (string) $hash;
    }

    /**
     * Get the hash algorithm for HMAC authentication
     *
     * @return string
     */
    public function getHashAlgorithm()
    {
        return $this->hash;
    }

    /**
     * Set the hash algorithm for the Pbkdf2
     *
     * @param  string                             $hash
     * @throws Exception\InvalidArgumentException
     */
    public function setPbkdf2HashAlgorithm($hash)
    {
        if (!Hash::isSupported($hash)) {
            throw new Exception\InvalidArgumentException(
                "The specified hash algorithm '{$hash}' is not supported by Laminas\Crypt\Hash"
            );
        }
        $this->pbkdf2Hash = (string) $hash;
    }

    /**
     * Get the Pbkdf2 hash algorithm
     *
     * @return string
     */
    public function getPbkdf2HashAlgorithm()
    {
        return $this->pbkdf2Hash;
    }

    /**
     * Encrypt then authenticate a file using HMAC
     *
     * @param  string                             $fileIn
     * @param  string                             $fileOut
     * @return bool
     * @throws Exception\InvalidArgumentException
     */
    public function encrypt($fileIn, $fileOut)
    {
        $this->checkFileInOut($fileIn, $fileOut);
        if (empty($this->key)) {
            throw new Exception\InvalidArgumentException('No key specified for encryption');
        }

        $read    = fopen($fileIn, "r");
        $write   = fopen($fileOut, "w");
        $iv      = Rand::getBytes($this->cipher->getSaltSize(), true);
        $keys    = Pbkdf2::calc($this->getPbkdf2HashAlgorithm(),
                                $this->getKey(),
                                $iv,
                                $this->getKeyIteration(),
                                $this->cipher->getKeySize() * 2);
        $hmac    = '';
        $size    = 0;
        $tot     = filesize($fileIn);
        $padding = $this->cipher->getPadding();

        $this->cipher->setKey(substr($keys, 0, $this->cipher->getKeySize()));
        $this->cipher->setPadding(new Symmetric\Padding\NoPadding);
        $this->cipher->setSalt($iv);
        $this->cipher->setMode('cbc');

        $hashAlgo  = $this->getHashAlgorithm();
        $saltSize  = $this->cipher->getSaltSize();
        $algorithm = $this->cipher->getAlgorithm();
        $keyHmac   = substr($keys, $this->cipher->getKeySize());

        while ($data = fread($read, self::BUFFER_SIZE)) {
            $size += strlen($data);
            // Padding if last block
            if ($size == $tot) {
                $this->cipher->setPadding($padding);
            }
            $result = $this->cipher->encrypt($data);
            if ($size <= self::BUFFER_SIZE) {
                // Write a placeholder for the HMAC and write the IV
                fwrite($write, str_repeat(0, Hmac::getOutputSize($hashAlgo)));
            } else {
                $result = substr($result, $saltSize);
            }
            $hmac = Hmac::compute($keyHmac,
                                  $hashAlgo,
                                  $algorithm . $hmac . $result);
            $this->cipher->setSalt(substr($result, -1 * $saltSize));
            if (fwrite($write, $result) !== strlen($result)) {
                return false;
            }
        }
        $result = true;
        // write the HMAC at the beginning of the file
        fseek($write, 0);
        if (fwrite($write, $hmac) !== strlen($hmac)) {
            $result = false;
        }
        fclose($write);
        fclose($read);

        return $result;
    }

    /**
     * Decrypt a file
     *
     * @param  string                             $fileIn
     * @param  string                             $fileOut
     * @param  bool                               $compress
     * @return bool
     * @throws Exception\InvalidArgumentException
     */
    public function decrypt($fileIn, $fileOut)
    {
        $this->checkFileInOut($fileIn, $fileOut);
        if (empty($this->key)) {
            throw new Exception\InvalidArgumentException('No key specified for decryption');
        }

        $read     = fopen($fileIn, "r");
        $write    = fopen($fileOut, "w");
        $hmacRead = fread($read, Hmac::getOutputSize($this->getHashAlgorithm()));
        $iv       = fread($read, $this->cipher->getSaltSize());
        $tot      = filesize($fileIn);
        $hmac     = $iv;
        $size     = strlen($iv) + strlen($hmacRead);
        $keys     = Pbkdf2::calc($this->getPbkdf2HashAlgorithm(),
                                 $this->getKey(),
                                 $iv,
                                 $this->getKeyIteration(),
                                 $this->cipher->getKeySize() * 2);
        $padding  = $this->cipher->getPadding();
        $this->cipher->setPadding(new Symmetric\Padding\NoPadding);
        $this->cipher->setKey(substr($keys, 0, $this->cipher->getKeySize()));
        $this->cipher->setMode('cbc');

        $blockSize = $this->cipher->getBlockSize();
        $hashAlgo  = $this->getHashAlgorithm();
        $algorithm = $this->cipher->getAlgorithm();
        $saltSize  = $this->cipher->getSaltSize();
        $keyHmac   = substr($keys, $this->cipher->getKeySize());

        while ($data = fread($read, self::BUFFER_SIZE)) {
            $size += strlen($data);
            // Unpadding if last block
            if ($size + $blockSize >= $tot) {
                $this->cipher->setPadding($padding);
                $data .= fread($read, $blockSize);
            }
            $result = $this->cipher->decrypt($iv . $data);
            $hmac   = Hmac::compute($keyHmac,
                                    $hashAlgo,
                                    $algorithm . $hmac . $data);
            $iv     = substr($data, -1 * $saltSize);
            if (fwrite($write, $result) !== strlen($result)) {
                return false;
            }
        }
        fclose($write);
        fclose($read);

        // check for data integrity
        if (!Utils::compareStrings($hmac, $hmacRead)) {
            unlink($fileOut);
            return false;
        }

        return true;
    }

    /**
     * Check that input file exists and output file dont
     *
     * @param  string $fileIn
     * @param  string $fileOut
     * @throws Exception\InvalidArgumentException
     */
    protected function checkFileInOut($fileIn, $fileOut)
    {
        if (!file_exists($fileIn)) {
            throw new Exception\InvalidArgumentException(sprintf(
                "I cannot open the %s file", $fileIn
            ));
        }
        if (file_exists($fileOut)) {
            throw new Exception\InvalidArgumentException(sprintf(
                "The file %s already exists", $fileOut
            ));
        }
    }
}