You are here

public static function ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push in Automatic Updates 7

Same name and namespace in other branches
  1. 8 vendor/paragonie/sodium_compat/src/Crypto32.php \ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push()

Parameters

string $state:

string $msg:

string $aad:

int $tag:

Return value

string

Throws

SodiumException

1 call to ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push()
ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_push in vendor/paragonie/sodium_compat/src/Compat.php

File

vendor/paragonie/sodium_compat/src/Crypto32.php, line 1297

Class

ParagonIE_Sodium_Crypto32
Class ParagonIE_Sodium_Crypto

Code

public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) {
  $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state);

  # crypto_onetimeauth_poly1305_state poly1305_state;

  # unsigned char                     block[64U];

  # unsigned char                     slen[8U];

  # unsigned char                    *c;

  # unsigned char                    *mac;
  $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg);
  $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad);
  if ($msglen + 63 >> 6 > 0xfffffffe) {
    throw new SodiumException('message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes');
  }

  # if (outlen_p != NULL) {

  #     *outlen_p = 0U;

  # }

  # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) {

  #     sodium_misuse();

  # }

  # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k);

  # crypto_onetimeauth_poly1305_init(&poly1305_state, block);

  # sodium_memzero(block, sizeof block);
  $auth = new ParagonIE_Sodium_Core32_Poly1305_State(ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st
    ->getCombinedNonce(), $st
    ->getKey()));

  # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen);
  $auth
    ->update($aad);

  # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0,

  #     (0x10 - adlen) & 0xf);
  $auth
    ->update(str_repeat("\0", 0x10 - $aadlen & 0xf));

  # memset(block, 0, sizeof block);

  # block[0] = tag;

  # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block,

  #                                    state->nonce, 1U, state->k);
  $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc(ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63), $st
    ->getCombinedNonce(), $st
    ->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(1));

  # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block);
  $auth
    ->update($block);

  # out[0] = block[0];
  $out = $block[0];

  # c = out + (sizeof tag);

  # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k);
  $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc($msg, $st
    ->getCombinedNonce(), $st
    ->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(2));

  # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen);
  $auth
    ->update($cipher);
  $out .= $cipher;
  unset($cipher);

  # crypto_onetimeauth_poly1305_update

  # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf);
  $auth
    ->update(str_repeat("\0", 0x10 - 64 + $msglen & 0xf));

  # STORE64_LE(slen, (uint64_t) adlen);
  $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen);

  # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
  $auth
    ->update($slen);

  # STORE64_LE(slen, (sizeof block) + mlen);
  $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen);

  # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen);
  $auth
    ->update($slen);

  # mac = c + mlen;

  # crypto_onetimeauth_poly1305_final(&poly1305_state, mac);
  $mac = $auth
    ->finish();
  $out .= $mac;

  # sodium_memzero(&poly1305_state, sizeof poly1305_state);
  unset($auth);

  # XOR_BUF(STATE_INONCE(state), mac,

  #     crypto_secretstream_xchacha20poly1305_INONCEBYTES);
  $st
    ->xorNonce($mac);

  # sodium_increment(STATE_COUNTER(state),

  #     crypto_secretstream_xchacha20poly1305_COUNTERBYTES);
  $st
    ->incrementCounter();

  // Overwrite by reference:
  $state = $st
    ->toString();

  /** @var bool $rekey */
  $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0;

  # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||

  #     sodium_is_zero(STATE_COUNTER(state),

  #         crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {

  #     crypto_secretstream_xchacha20poly1305_rekey(state);

  # }
  if ($rekey || $st
    ->needsRekey()) {

    // DO REKEY
    self::secretstream_xchacha20poly1305_rekey($state);
  }

  # if (outlen_p != NULL) {

  #     *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen;

  # }
  return $out;
}