You are here

protected static function ParagonIE_Sodium_File::secretbox_encrypt in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/File.php \ParagonIE_Sodium_File::secretbox_encrypt()

Encrypt a file

Parameters

resource $ifp:

resource $ofp:

int $mlen:

string $nonce:

string $key:

Return value

bool

Throws

SodiumException

TypeError

2 calls to ParagonIE_Sodium_File::secretbox_encrypt()
ParagonIE_Sodium_File::box_encrypt in vendor/paragonie/sodium_compat/src/File.php
ParagonIE_Sodium_File::secretbox in vendor/paragonie/sodium_compat/src/File.php
Encrypt a file (rather than a string). Uses less memory than ParagonIE_Sodium_Compat::crypto_secretbox(), but produces the same result.

File

vendor/paragonie/sodium_compat/src/File.php, line 842

Class

ParagonIE_Sodium_File
Class ParagonIE_Sodium_File

Code

protected static function secretbox_encrypt($ifp, $ofp, $mlen, $nonce, $key) {
  if (PHP_INT_SIZE === 4) {
    return self::secretbox_encrypt_core32($ifp, $ofp, $mlen, $nonce, $key);
  }
  $plaintext = fread($ifp, 32);
  if (!is_string($plaintext)) {
    throw new SodiumException('Could not read input file');
  }
  $first32 = self::ftell($ifp);

  /** @var string $subkey */
  $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key);

  /** @var string $realNonce */
  $realNonce = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8);

  /** @var string $block0 */
  $block0 = str_repeat("\0", 32);

  /** @var int $mlen - Length of the plaintext message */
  $mlen0 = $mlen;
  if ($mlen0 > 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES) {
    $mlen0 = 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES;
  }
  $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0);

  /** @var string $block0 */
  $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20_xor($block0, $realNonce, $subkey);
  $state = new ParagonIE_Sodium_Core_Poly1305_State(ParagonIE_Sodium_Core_Util::substr($block0, 0, ParagonIE_Sodium_Crypto::onetimeauth_poly1305_KEYBYTES));

  // Pre-write 16 blank bytes for the Poly1305 tag
  $start = self::ftell($ofp);
  fwrite($ofp, str_repeat("\0", 16));

  /** @var string $c */
  $cBlock = ParagonIE_Sodium_Core_Util::substr($block0, ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES);
  $state
    ->update($cBlock);
  fwrite($ofp, $cBlock);
  $mlen -= 32;

  /** @var int $iter */
  $iter = 1;

  /** @var int $incr */
  $incr = self::BUFFER_SIZE >> 6;

  /*
   * Set the cursor to the end of the first half-block. All future bytes will
   * generated from salsa20_xor_ic, starting from 1 (second block).
   */
  fseek($ifp, $first32, SEEK_SET);
  while ($mlen > 0) {
    $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen;
    $plaintext = fread($ifp, $blockSize);
    if (!is_string($plaintext)) {
      throw new SodiumException('Could not read input file');
    }
    $cBlock = ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic($plaintext, $realNonce, $iter, $subkey);
    fwrite($ofp, $cBlock, $blockSize);
    $state
      ->update($cBlock);
    $mlen -= $blockSize;
    $iter += $incr;
  }
  try {
    ParagonIE_Sodium_Compat::memzero($block0);
    ParagonIE_Sodium_Compat::memzero($subkey);
  } catch (SodiumException $ex) {
    $block0 = null;
    $subkey = null;
  }
  $end = self::ftell($ofp);

  /*
   * Write the Poly1305 authentication tag that provides integrity
   * over the ciphertext (encrypt-then-MAC)
   */
  fseek($ofp, $start, SEEK_SET);
  fwrite($ofp, $state
    ->finish(), ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES);
  fseek($ofp, $end, SEEK_SET);
  unset($state);
  return true;
}