Ejemplo n.º 1
0
 /**
  * Stream encryption - Do not call directly
  *
  * @param ReadOnlyFile $input
  * @param MutableFile $output
  * @param EncryptionKey $encKey
  * @param string $nonce
  * @param resource $mac (hash context)
  * @param Config $config
  * @return int
  * @throws CryptoException\AccessDenied
  * @throws CryptoException\FileModified
  * @throws CryptoException\InvalidKey
  */
 private static final function streamEncrypt(ReadOnlyFile $input, MutableFile $output, EncryptionKey $encKey, string $nonce, $mac, Config $config) : int
 {
     $initHash = $input->getHash();
     // Begin the streaming decryption
     $size = $input->getSize();
     while ($input->remainingBytes() > 0) {
         $read = $input->readBytes($input->getPos() + $config->BUFFER > $size ? $size - $input->getPos() : $config->BUFFER);
         $encrypted = \Sodium\crypto_stream_xor($read, $nonce, $encKey->getRawKeyMaterial());
         if ($config->USE_BLAKE2B) {
             \Sodium\crypto_generichash_update($mac, $encrypted);
         } else {
             \hash_update($mac, $encrypted);
         }
         $output->writeBytes($encrypted);
         \Sodium\increment($nonce);
     }
     \Sodium\memzero($nonce);
     // Check that our input file was not modified before we MAC it
     if (!\hash_equals($input->gethash(), $initHash)) {
         throw new CryptoException\FileModified('Read-only file has been modified since it was opened for reading');
     }
     if ($config->USE_BLAKE2B) {
         return $output->writeBytes(\Sodium\crypto_generichash_final($mac, $config->MAC_SIZE), $config->MAC_SIZE);
     }
     return $output->writeBytes(\hash_final($mac, true));
 }