ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_push

Advertisement

Syntax Syntax

ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_push( string $state, string $msg, string $aad = '', int $tag )

Parameters Parameters

$state

(Required)

$msg

(Required)

$aad

(Optional)

Default value: ''

$tag

(Required)

Return Return

(string)

Source Source

File: wp-includes/sodium_compat/src/Crypto.php

    public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0)
    {
        $st = ParagonIE_Sodium_Core_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_Core_Util::strlen($msg);
        $aadlen = ParagonIE_Sodium_Core_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_Core_Poly1305_State(
            ParagonIE_Sodium_Core_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_Core_ChaCha20::ietfStreamXorIc(
            ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63),
            $st->getCombinedNonce(),
            $st->getKey(),
            ParagonIE_Sodium_Core_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_Core_ChaCha20::ietfStreamXorIc(
            $msg,
            $st->getCombinedNonce(),
            $st->getKey(),
            ParagonIE_Sodium_Core_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_Core_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_Core_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;
    }

Advertisement

Advertisement

Leave a Reply