35    private const CHECKSUM_ALGO = 
"sha256";
 
   37    public static bool $ENABLED = 
true;
 
   41    private Cipher $decryptCipher;
 
   42    private int $decryptCounter = 0;
 
   44    private Cipher $encryptCipher;
 
   45    private int $encryptCounter = 0;
 
   47    public function __construct(
string $encryptionKey, 
string $algorithm, 
string $iv){
 
   48        $this->key = $encryptionKey;
 
   50        $this->decryptCipher = 
new Cipher($algorithm);
 
   51        $this->decryptCipher->decryptInit($this->key, $iv);
 
   53        $this->encryptCipher = 
new Cipher($algorithm);
 
   54        $this->encryptCipher->encryptInit($this->key, $iv);
 
   67    public static function fakeGCM(
string $encryptionKey) : self{
 
   71            substr($encryptionKey, 0, 12) . 
"\x00\x00\x00\x02" 
 
   75    public static function cfb8(
string $encryptionKey) : self{
 
   79            substr($encryptionKey, 0, 16)
 
   86    public function decrypt(
string $encrypted) : string{
 
   87        if(strlen($encrypted) < 9){
 
   90        $decrypted = $this->decryptCipher->decryptUpdate($encrypted);
 
   91        $payload = substr($decrypted, 0, -8);
 
   93        $packetCounter = $this->decryptCounter++;
 
   95        if(($expected = $this->calculateChecksum($packetCounter, $payload)) !== ($actual = substr($decrypted, -8))){
 
   96            throw new DecryptionException(
"Encrypted packet $packetCounter has invalid checksum (expected " . bin2hex($expected) . 
", got " . bin2hex($actual) . 
")");
 
 
  102    public function encrypt(
string $payload) : string{
 
  103        return $this->encryptCipher->encryptUpdate($payload . $this->calculateChecksum($this->encryptCounter++, $payload));
 
  106    private function calculateChecksum(
int $counter, 
string $payload) : string{
 
  107        $hash = openssl_digest(LE::packUnsignedLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true);
 
  109            throw new \RuntimeException(
"openssl_digest() error: " . openssl_error_string());
 
  111        return substr($hash, 0, 8);
 
 
static fakeGCM(string $encryptionKey)