function test_hash($algo, $init)
{
    echo "\n{$algo}, incremental: ";
    $h = hash_init($algo);
    for ($i = 0; $i < 10; ++$i) {
        hash_update($h, '' . $init * 2 + $i * 17);
    }
    echo '(copying state) ';
    $h2 = hash_copy($h);
    for ($i = 0; $i < 10; ++$i) {
        hash_update($h, '' . $init * 2 + $i * 19);
    }
    var_dump(hash_final($h));
    echo "\n{$algo}, from copied state: ";
    var_dump(hash_final($h2));
    echo "\n{$algo}, HMAC, incremental: ";
    $h = hash_init($algo, HASH_HMAC, 'HMAC key. It can be very long, but in this case it will be rehashed to fit the block size of the hashing algorithm...' . $init * 147);
    for ($i = 0; $i < 10; ++$i) {
        hash_update($h, '' . $init * 4 + $i * 7);
    }
    //echo '(copying state) ';
    //$h2 = hash_copy($h);// causes PHP crashes sometimes, reported as PHP Bug #52240
    for ($i = 0; $i < 10; ++$i) {
        hash_update($h, '' . $init * 3 + $i * 11);
    }
    var_dump(hash_final($h));
    //echo "\n$algo, HMAC, from copied state: ";
    //var_dump(hash_final($h2));// BUG IN PHP, HMAC key is not copied, but only referenced ... hash_final on $h clears the HMAC key in $h2 too...  reported as PHP Bug #52240
    echo "\n{$algo}, at once, short data: ";
    var_dump(hash($algo, 'some string to be hashed ... ' . $init * 123 . ' ...'));
    echo "\n{$algo}, at once, HMAC: ";
    var_dump(hash_hmac($algo, 'some string to be hashed ... ' . $init * 123 . ' ...', 'HMAC key. It can be very long, but in this case it will be rehashed to fit the block size of the hashing algorithm.'));
}
 /**
  * Copy a hashing context.
  * (PHP 5 >= 5.3.0)
  *
  * @param resource
  * @return resource
  */
 public final function copy($context)
 {
     if (!is_resource($context)) {
         return false;
     }
     return hash_copy($context);
 }
Example #3
0
 /**
  * {@inheritDoc}
  */
 public function digest()
 {
     // Copy the context so we can keep using the hasher
     $context_copy = hash_copy($this->context);
     // Calculate the digest
     $digest = hash_final($this->context, true);
     // Set our context to the copied one, since the old one is now finalized
     $this->context = $context_copy;
     return $digest;
 }
 function Save()
 {
     // ASSERTION - There is no volatile data
     if ($this->status == 0) {
         // We haven't called Open() yet so just return the status, everything can be left defaults on Load()
         return array('status' => $this->status);
     }
     // Convert hash_ctx into CRC field
     if ($this->hash_ctx !== false && $this->hash_len != 0) {
         $copy_ctx = hash_copy($this->hash_ctx);
         list($hash_ctx) = array_values(unpack('N', hash_final($copy_ctx, true)));
     } else {
         $hash_ctx = false;
     }
     return array('status' => $this->status, 'cipher_spec' => $this->cipher_spec, 'key' => $this->key, 'iv' => $this->iv, 'real_blocksize' => $this->real_blocksize, 'blocksize' => $this->blocksize, 'data' => $this->data, 'data_len' => $this->data_len, 'crc' => $this->crc, 'hash_ctx' => $hash_ctx, 'hash_len' => $this->hash_len, 'totalsize' => $this->totalsize, 'encsize' => $this->encsize, 'last_cipher' => $this->last_cipher, 'buffer_disk' => $this->buffer_disk === false ? false : $this->buffer_disk->Save(), 'volatile' => $this->volatile, 'volatile_len' => $this->volatile_len, 'header_pos' => $this->header_pos);
 }
 function Save()
 {
     // Return the state
     $state = array('rolling_size' => $this->rolling_size);
     // Convert hash_ctx into CRC field
     if ($this->rolling_size !== false) {
         $state['rolling_crc'] = $this->rolling_crc;
         if ($this->rolling_hash_ctx !== false && $this->rolling_hash_len) {
             $copy_ctx = hash_copy($this->rolling_hash_ctx);
             $state['rolling_hash_ctx'] = hexdec(hash_final($copy_ctx, false));
             $state['rolling_hash_len'] = $this->rolling_hash_len;
         } else {
             $state['rolling_hash_ctx'] = false;
         }
     }
     return $state;
 }
Example #6
0
 /**
  * Recalculate and verify the HMAC of the input file
  *
  * @param resource $input
  * @param resource|string $mac (hash context)
  * @param Config $config
  *
  * @return array Hashes of various chunks
  * @throws CryptoException\CannotPerformOperation
  * @throws CryptoException\InvalidMessage
  */
 private static final function streamVerify(ReadOnlyFile $input, $mac, Config $config) : array
 {
     $start = $input->getPos();
     $cipher_end = $input->getSize() - $config->MAC_SIZE;
     $input->reset($cipher_end);
     $stored_mac = $input->readBytes($config->MAC_SIZE);
     $input->reset($start);
     $chunk_macs = [];
     $break = false;
     while (!$break && $input->getPos() < $cipher_end) {
         /**
          * Would a full BUFFER read put it past the end of the
          * ciphertext? If so, only return a portion of the file.
          */
         if ($input->getPos() + $config->BUFFER >= $cipher_end) {
             $break = true;
             $read = $input->readBytes($cipher_end - $input->getPos());
         } else {
             $read = $input->readBytes($config->BUFFER);
         }
         /**
          * We're updating our HMAC and nothing else
          */
         if ($config->USE_BLAKE2B) {
             \Sodium\crypto_generichash_update($mac, $read);
             $chunkMAC = '' . $mac;
             $chunk_macs[] = \Sodium\crypto_generichash_final($chunkMAC, $config->MAC_SIZE);
         } else {
             \hash_update($mac, $read);
             /**
              * Store a MAC of each chunk
              */
             $chunkMAC = \hash_copy($mac);
             if ($chunkMAC === false) {
                 throw new CryptoException\CannotPerformOperation('An unknown error has occurred');
             }
             $chunk_macs[] = \hash_final($chunkMAC, true);
         }
     }
     /**
      * We should now have enough data to generate an identical HMAC
      */
     if ($config->USE_BLAKE2B) {
         $finalHMAC = \Sodium\crypto_generichash_final($mac, $config->MAC_SIZE);
     } else {
         $finalHMAC = \hash_final($mac, true);
     }
     /**
      * Use hash_equals() to be timing-invariant
      */
     if (!\hash_equals($finalHMAC, $stored_mac)) {
         throw new CryptoException\InvalidMessage('Invalid message authentication code');
     }
     $input->reset($start);
     return $chunk_macs;
 }
Example #7
0
<?php

$algos = hash_algos();
foreach ($algos as $algo) {
    var_dump($algo);
    $orig = hash_init($algo);
    hash_update($orig, "I can't remember anything");
    $copy = hash_copy($orig);
    var_dump(hash_final($orig));
    var_dump(hash_final($copy));
}
foreach ($algos as $algo) {
    var_dump($algo);
    $orig = hash_init($algo);
    hash_update($orig, "I can't remember anything");
    $copy = hash_copy($orig);
    var_dump(hash_final($orig));
    hash_update($copy, "Can’t tell if this is true or dream");
    var_dump(hash_final($copy));
}
echo "Done\n";
Example #8
0
File: Hash.php Project: mleko/hash
 /**
  * @param bool|false $raw
  * @return string
  */
 public function result($raw = false)
 {
     $context = hash_copy($this->context);
     return hash_final($context, $raw);
 }
Example #9
0
<?php

$c = hash_init("crc32");
hash_update($c, "Hello");
$d = hash_copy($c);
hash_update($c, "World");
hash_update($d, "Goodbye");
var_dump(hash_final($c));
var_dump(hash("crc32", "HelloWorld"));
var_dump(hash_final($d));
var_dump(hash("crc32", "HelloGoodbye"));
Example #10
0
<?php

$h = hash_init('crc32b', HASH_HMAC, '123456');
$h2 = hash_copy($h);
var_dump(hash_final($h));
$h3 = hash_copy($h2);
var_dump(hash_final($h2));
var_dump(hash_final($h3));
Example #11
0
 /**
  * Decrypt the contents of a file handle $inputHandle and store the results
  * in $outputHandle using HKDF of $key to decrypt then verify
  *
  * @param resource $inputHandle
  * @param resource $outputHandle
  * @param Key $key
  * @return boolean
  */
 public static function decryptResource($inputHandle, $outputHandle, Key $key)
 {
     // Because we don't have strict typing in PHP 5
     if (!\is_resource($inputHandle)) {
         throw new Ex\InvalidInput('Input handle must be a resource!');
     }
     if (!\is_resource($outputHandle)) {
         throw new Ex\InvalidInput('Output handle must be a resource!');
     }
     // Parse the header.
     $header = self::readBytes($inputHandle, Core::HEADER_VERSION_SIZE);
     $config = self::getFileVersionConfigFromHeader($header, Core::CURRENT_FILE_VERSION);
     // Let's add this check before anything
     if (!\in_array($config->hashFunctionName(), \hash_algos())) {
         throw new Ex\CannotPerformOperationException('The specified hash function does not exist');
     }
     // Let's grab the file salt.
     $file_salt = self::readBytes($inputHandle, $config->saltByteSize());
     // For storing MACs of each buffer chunk
     $macs = [];
     /**
      * 1. We need to decode some values from our files
      */
     /**
      * Let's split our keys
      *
      * $ekey -- Encryption Key -- used for AES
      */
     $ekey = Core::HKDF($config->hashFunctionName(), $key->getRawBytes(), $config->keyByteSize(), $config->encryptionInfoString(), $file_salt, $config);
     /**
      * $akey -- Authentication Key -- used for HMAC
      */
     $akey = Core::HKDF($config->hashFunctionName(), $key->getRawBytes(), $config->keyByteSize(), $config->authenticationInfoString(), $file_salt, $config);
     /**
      * Grab our IV from the encrypted message
      *
      * It should be the first N blocks of the file (N = 16)
      */
     $ivsize = \openssl_cipher_iv_length($config->cipherMethod());
     $iv = self::readBytes($inputHandle, $ivsize);
     // How much do we increase the counter after each buffered encryption to prevent nonce reuse
     $inc = $config->bufferByteSize() / $config->blockByteSize();
     $thisIv = $iv;
     /**
      * Let's grab our MAC
      *
      * It should be the last N blocks of the file (N = 32)
      */
     if (\fseek($inputHandle, -1 * $config->macByteSize(), SEEK_END) === false) {
         throw new Ex\CannotPerformOperationException('Cannot seek to beginning of MAC within input file');
     }
     // Grab our last position of ciphertext before we read the MAC
     $cipher_end = \ftell($inputHandle);
     if ($cipher_end === false) {
         throw new Ex\CannotPerformOperationException('Cannot read input file');
     }
     --$cipher_end;
     // We need to subtract one
     // We keep our MAC stored in this variable
     $stored_mac = self::readBytes($inputHandle, $config->macByteSize());
     /**
      * We begin recalculating the HMAC for the entire file...
      */
     $hmac = \hash_init($config->hashFunctionName(), HASH_HMAC, $akey);
     if ($hmac === false) {
         throw new Ex\CannotPerformOperationException('Cannot initialize a hash context');
     }
     /**
      * Reset file pointer to the beginning of the file after the header
      */
     if (\fseek($inputHandle, Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
         throw new Ex\CannotPerformOperationException('Cannot read seek within input file');
     }
     /**
      * Set it to the first non-salt and non-IV byte
      */
     if (\fseek($inputHandle, $config->saltByteSize() + $ivsize, SEEK_CUR) === false) {
         throw new Ex\CannotPerformOperationException('Cannot read seek input file to beginning of ciphertext');
     }
     /**
      * 2. Let's recalculate the MAC
      */
     /**
      * Let's initialize our $hmac hasher with our Salt and IV
      */
     \hash_update($hmac, $header);
     \hash_update($hmac, $file_salt);
     \hash_update($hmac, $iv);
     $hmac2 = \hash_copy($hmac);
     $break = false;
     while (!$break) {
         /**
          * First, grab the current position
          */
         $pos = \ftell($inputHandle);
         if ($pos === false) {
             throw new Ex\CannotPerformOperationException('Could not get current position in input file during decryption');
         }
         /**
          * Would a full DBUFFER read put it past the end of the
          * ciphertext? If so, only return a portion of the file.
          */
         if ($pos + $config->bufferByteSize() >= $cipher_end) {
             $break = true;
             $read = self::readBytes($inputHandle, $cipher_end - $pos + 1);
         } else {
             $read = self::readBytes($inputHandle, $config->bufferByteSize());
         }
         if ($read === false) {
             throw new Ex\CannotPerformOperationException('Could not read input file during decryption');
         }
         /**
          * We're updating our HMAC and nothing else
          */
         \hash_update($hmac, $read);
         /**
          * Store a MAC of each chunk
          */
         $chunkMAC = \hash_copy($hmac);
         if ($chunkMAC === false) {
             throw new Ex\CannotPerformOperationException('Cannot duplicate a hash context');
         }
         $macs[] = \hash_final($chunkMAC);
     }
     /**
      * We should now have enough data to generate an identical HMAC
      */
     $finalHMAC = \hash_final($hmac, true);
     /**
      * 3. Did we match?
      */
     if (!Core::hashEquals($finalHMAC, $stored_mac)) {
         throw new Ex\InvalidCiphertextException('Message Authentication failure; tampering detected.');
     }
     /**
      * 4. Okay, let's begin decrypting
      */
     /**
      * Return file pointer to the first non-header, non-IV byte in the file
      */
     if (\fseek($inputHandle, $config->saltByteSize() + $ivsize + Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
         throw new Ex\CannotPerformOperationException('Could not move the input file pointer during decryption');
     }
     /**
      * Should we break the writing?
      */
     $breakW = false;
     /**
      * This loop writes plaintext to the destination file:
      */
     while (!$breakW) {
         /**
          * Get the current position
          */
         $pos = \ftell($inputHandle);
         if ($pos === false) {
             throw new Ex\CannotPerformOperationException('Could not get current position in input file during decryption');
         }
         /**
          * Would a full BUFFER read put it past the end of the
          * ciphertext? If so, only return a portion of the file.
          */
         if ($pos + $config->bufferByteSize() >= $cipher_end) {
             $breakW = true;
             $read = self::readBytes($inputHandle, $cipher_end - $pos + 1);
         } else {
             $read = self::readBytes($inputHandle, $config->bufferByteSize());
         }
         /**
          * Recalculate the MAC, compare with the one stored in the $macs
          * array to ensure attackers couldn't tamper with the file
          * after MAC verification
          */
         \hash_update($hmac2, $read);
         $calcMAC = \hash_copy($hmac2);
         if ($calcMAC === false) {
             throw new Ex\CannotPerformOperationException('Cannot duplicate a hash context');
         }
         $calc = \hash_final($calcMAC);
         if (empty($macs)) {
             throw new Ex\InvalidCiphertextException('File was modified after MAC verification');
         } elseif (!Core::hashEquals(\array_shift($macs), $calc)) {
             throw new Ex\InvalidCiphertextException('File was modified after MAC verification');
         }
         $thisIv = Core::incrementCounter($thisIv, $inc, $config);
         /**
          * Perform the AES decryption. Decrypts the message.
          */
         $decrypted = \openssl_decrypt($read, $config->cipherMethod(), $ekey, OPENSSL_RAW_DATA, $thisIv);
         /**
          * Test for decryption faulure
          */
         if ($decrypted === false) {
             throw new Ex\CannotPerformOperationException('OpenSSL decryption error');
         }
         /**
          * Write the plaintext out to the output file
          */
         self::writeBytes($outputHandle, $decrypted, Core::ourStrlen($decrypted));
     }
     return true;
 }
Example #12
0
 /**
  * @ignore
  */
 public function __clone()
 {
     $this->m_hashingContext = hash_copy($this->m_hashingContext);
 }
Example #13
0
 public function __clone()
 {
     // copy the hash so we dont tamper with the original (e.g. hash_final
     // will pad and corrupt it if we get the value of it.)
     $this->hash = hash_copy($this->hash);
 }
Example #14
0
 /**
  * Decrypts a file-backed resource with either a key or a password.
  *
  * @param resource      $inputHandle
  * @param resource      $outputHandle
  * @param KeyOrPassword $secret
  *
  * @throws Defuse\Crypto\Exception\EnvironmentIsBrokenException
  * @throws Defuse\Crypto\Exception\IOException
  * @throws Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException
  */
 public static function decryptResourceInternal($inputHandle, $outputHandle, KeyOrPassword $secret)
 {
     if (!\is_resource($inputHandle)) {
         throw new Ex\IOException('Input handle must be a resource!');
     }
     if (!\is_resource($outputHandle)) {
         throw new Ex\IOException('Output handle must be a resource!');
     }
     /* Make sure the file is big enough for all the reads we need to do. */
     $stat = \fstat($inputHandle);
     if ($stat['size'] < Core::MINIMUM_CIPHERTEXT_SIZE) {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Input file is too small to have been created by this library.');
     }
     /* Check the version header. */
     $header = self::readBytes($inputHandle, Core::HEADER_VERSION_SIZE);
     if ($header !== Core::CURRENT_VERSION) {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Bad version header.');
     }
     /* Get the salt. */
     $file_salt = self::readBytes($inputHandle, Core::SALT_BYTE_SIZE);
     /* Get the IV. */
     $ivsize = Core::BLOCK_BYTE_SIZE;
     $iv = self::readBytes($inputHandle, $ivsize);
     /* Derive the authentication and encryption keys. */
     $keys = $secret->deriveKeys($file_salt);
     $ekey = $keys->getEncryptionKey();
     $akey = $keys->getAuthenticationKey();
     /* We'll store the MAC of each buffer-sized chunk as we verify the
      * actual MAC, so that we can check them again when decrypting. */
     $macs = [];
     /* $thisIv will be incremented after each call to the decryption. */
     $thisIv = $iv;
     /* How many blocks do we encrypt at a time? We increment by this value. */
     $inc = Core::BUFFER_BYTE_SIZE / Core::BLOCK_BYTE_SIZE;
     /* Get the HMAC. */
     if (\fseek($inputHandle, -1 * Core::MAC_BYTE_SIZE, SEEK_END) === false) {
         throw new Ex\IOException('Cannot seek to beginning of MAC within input file');
     }
     /* Get the position of the last byte in the actual ciphertext. */
     $cipher_end = \ftell($inputHandle);
     if ($cipher_end === false) {
         throw new Ex\IOException('Cannot read input file');
     }
     /* We have the position of the first byte of the HMAC. Go back by one. */
     --$cipher_end;
     /* Read the HMAC. */
     $stored_mac = self::readBytes($inputHandle, Core::MAC_BYTE_SIZE);
     /* Initialize a streaming HMAC state. */
     $hmac = \hash_init(Core::HASH_FUNCTION_NAME, HASH_HMAC, $akey);
     if ($hmac === false) {
         throw new Ex\EnvironmentIsBrokenException('Cannot initialize a hash context');
     }
     /* Reset file pointer to the beginning of the file after the header */
     if (\fseek($inputHandle, Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
         throw new Ex\IOException('Cannot read seek within input file');
     }
     /* Seek to the start of the actual ciphertext. */
     if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize, SEEK_CUR) === false) {
         throw new Ex\IOException('Cannot seek input file to beginning of ciphertext');
     }
     /* PASS #1: Calculating the HMAC. */
     \hash_update($hmac, $header);
     \hash_update($hmac, $file_salt);
     \hash_update($hmac, $iv);
     $hmac2 = \hash_copy($hmac);
     $break = false;
     while (!$break) {
         $pos = \ftell($inputHandle);
         if ($pos === false) {
             throw new Ex\IOException('Could not get current position in input file during decryption');
         }
         /* Read the next buffer-sized chunk (or less). */
         if ($pos + Core::BUFFER_BYTE_SIZE >= $cipher_end) {
             $break = true;
             $read = self::readBytes($inputHandle, $cipher_end - $pos + 1);
         } else {
             $read = self::readBytes($inputHandle, Core::BUFFER_BYTE_SIZE);
         }
         /* Update the HMAC. */
         \hash_update($hmac, $read);
         /* Remember this buffer-sized chunk's HMAC. */
         $chunk_mac = \hash_copy($hmac);
         if ($chunk_mac === false) {
             throw new Ex\EnvironmentIsBrokenException('Cannot duplicate a hash context');
         }
         $macs[] = \hash_final($chunk_mac);
     }
     /* Get the final HMAC, which should match the stored one. */
     $final_mac = \hash_final($hmac, true);
     /* Verify the HMAC. */
     if (!Core::hashEquals($final_mac, $stored_mac)) {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Integrity check failed.');
     }
     /* PASS #2: Decrypt and write output. */
     /* Rewind to the start of the actual ciphertext. */
     if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize + Core::HEADER_VERSION_SIZE, SEEK_SET) === false) {
         throw new Ex\IOException('Could not move the input file pointer during decryption');
     }
     $at_file_end = false;
     while (!$at_file_end) {
         $pos = \ftell($inputHandle);
         if ($pos === false) {
             throw new Ex\IOException('Could not get current position in input file during decryption');
         }
         /* Read the next buffer-sized chunk (or less). */
         if ($pos + Core::BUFFER_BYTE_SIZE >= $cipher_end) {
             $at_file_end = true;
             $read = self::readBytes($inputHandle, $cipher_end - $pos + 1);
         } else {
             $read = self::readBytes($inputHandle, Core::BUFFER_BYTE_SIZE);
         }
         /* Recalculate the MAC (so far) and compare it with the one we
          * remembered from pass #1 to ensure attackers didn't change the
          * ciphertext after MAC verification. */
         \hash_update($hmac2, $read);
         $calc_mac = \hash_copy($hmac2);
         if ($calc_mac === false) {
             throw new Ex\EnvironmentIsBrokenException('Cannot duplicate a hash context');
         }
         $calc = \hash_final($calc_mac);
         if (empty($macs)) {
             throw new Ex\WrongKeyOrModifiedCiphertextException('File was modified after MAC verification');
         } elseif (!Core::hashEquals(\array_shift($macs), $calc)) {
             throw new Ex\WrongKeyOrModifiedCiphertextException('File was modified after MAC verification');
         }
         /* Decrypt this buffer-sized chunk. */
         $decrypted = \openssl_decrypt($read, Core::CIPHER_METHOD, $ekey, OPENSSL_RAW_DATA, $thisIv);
         if ($decrypted === false) {
             throw new Ex\EnvironmentIsBrokenException('OpenSSL decryption error');
         }
         /* Write the plaintext to the output file. */
         self::writeBytes($outputHandle, $decrypted, Core::ourStrlen($decrypted));
         /* Increment the IV by the amount of blocks in a buffer. */
         $thisIv = Core::incrementCounter($thisIv, $inc);
         /* WARNING: Usually, unless the file is a multiple of the buffer
          * size, $thisIv will contain an incorrect value here on the last
          * iteration of this loop. */
     }
 }
Example #15
0
 function Save()
 {
     if ($this->hash_ctx !== false && $this->job !== false && $this->job['hash_len'] != 0) {
         $copy_ctx = hash_copy($this->hash_ctx);
         list($crc) = array_values(unpack('N', hash_final($copy_ctx, true)));
         // Save it in the job
         $this->job['saved_hash_ctx'] = $crc;
     }
 }
 function Save()
 {
     // Return the state
     $state = array('rolling_buffer' => $this->rolling_buffer);
     // Convert hash_ctx into CRC field
     if ($this->rolling_buffer !== false) {
         $state['rolling_len'] = $this->rolling_len;
         $state['rolling_size'] = $this->rolling_size;
         $state['rolling_crc'] = $this->rolling_crc;
         if ($this->rolling_hash_ctx !== false && $this->rolling_hash_len != 0) {
             $copy_ctx = hash_copy($this->rolling_hash_ctx);
             list($state['rolling_hash_ctx']) = array_values(unpack('N', hash_final($copy_ctx, true)));
             $state['rolling_hash_len'] = $this->rolling_hash_len;
         } else {
             $state['rolling_hash_ctx'] = false;
         }
         $state['rolling_tempfile'] = $this->rolling_tempfile !== false ? $this->rolling_tempfile->Save() : false;
         $state['rolling_gzipname'] = $this->rolling_gzipname;
     }
     return $state;
 }
Example #17
0
 public function __clone()
 {
     $handle = hash_copy($this->getHandle());
     $this->setHandle($handle);
 }
Example #18
0
 /**
  * Recalculate and verify the HMAC of the input file
  * 
  * @param resource $input
  * @param Key $authKey
  * @param resource $mac (hash context)
  * @param &array $config
  * @return Hashes of various chunks
  * @throws FileAlert\AccessDenied
  */
 private static final function streamVerify($input, $mac, array $config)
 {
     $start = \ftell($input);
     if (\fseek($input, -1 * $config['MAC_SIZE'], SEEK_END) === false) {
         throw new CryptoAlert\CannotPerformOperation('Stream error');
     }
     $cipher_end = \ftell($input) - 1;
     $stored_mac = self::readBytes($input, $config['MAC_SIZE']);
     if (\fseek($input, $start, SEEK_SET) === false) {
         throw new CryptoAlert\CannotPerformOperation('Stream error');
     }
     $chunk_macs = [];
     $break = false;
     while (!$break) {
         /**
          * First, grab the current position
          */
         $pos = \ftell($input);
         if ($pos === false) {
             throw new CryptoAlert\CannotPerformOperation('Stream error');
         }
         if ($pos >= $cipher_end) {
             break;
         }
         /**
          * Would a full BUFFER read put it past the end of the
          * ciphertext? If so, only return a portion of the file.
          */
         if ($pos + $config['BUFFER'] >= $cipher_end) {
             $break = true;
             $read = self::readBytes($input, $cipher_end - $pos + 1);
         } else {
             $read = self::readBytes($input, $config['BUFFER']);
         }
         /**
          * We're updating our HMAC and nothing else
          */
         \hash_update($mac, $read);
         /**
          * Store a MAC of each chunk
          */
         $chunkMAC = \hash_copy($mac);
         if ($chunkMAC === false) {
             throw new CryptoAlert\CannotPerformOperation('An unknown error has occurred');
         }
         $chunk_macs[] = \hash_final($chunkMAC, true);
     }
     /**
      * We should now have enough data to generate an identical HMAC
      */
     $finalHMAC = \hash_final($mac, true);
     if (!\hash_equals($finalHMAC, $stored_mac)) {
         throw new CryptoAlert\InvalidMessage('Invalid message authentication code');
     }
     if (\fseek($input, $start, SEEK_SET) === false) {
         throw new CryptoAlert\CannotPerformOperation('Stream error');
     }
     return $chunk_macs;
 }
Example #19
0
<?php

$r = hash_init("md5");
var_dump(hash_copy());
var_dump(hash_copy($r));
var_dump(hash_copy($r, $r));
echo "Done\n";
Example #20
0
 /**
  * {@inheritdoc}
  */
 public function __clone()
 {
     if ($this->context) {
         $this->context = hash_copy($this->context);
     }
 }
Example #21
0
<?php

$ctx = hash_init('md5');
hash_update($ctx, 'The quick brown fox ');
hash_update($ctx, 'jumped over the lazy dog.');
echo hash_final($ctx);
$ctx2 = hash_copy($ctx);
var_dump($ctx2);
var_dump(hash_update($ctx, 'The quick brown fox '));
var_dump(hash_final($ctx));