Skip to content

Add sodium_crypto_stream_xchacha20_xor_ic() #8276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions ext/sodium/libsodium.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,49 @@ PHP_FUNCTION(sodium_crypto_stream_xchacha20_xor)

RETURN_NEW_STR(ciphertext);
}

PHP_FUNCTION(sodium_crypto_stream_xchacha20_xor_ic)
{
zend_string *ciphertext;
unsigned char *key;
unsigned char *msg;
unsigned char *nonce;
zend_long *ic;

size_t ciphertext_len;
size_t key_len;
size_t msg_len;
size_t nonce_len;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssls",
&msg, &msg_len,
&nonce, &nonce_len,
&ic,
&key, &key_len) == FAILURE) {
sodium_remove_param_values_from_backtrace(EG(exception));
RETURN_THROWS();
}
if (nonce_len != crypto_stream_xchacha20_NONCEBYTES) {
zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES bytes long");
RETURN_THROWS();
}
if (key_len != crypto_stream_xchacha20_KEYBYTES) {
zend_argument_error(sodium_exception_ce, 3, "must be SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES bytes long");
RETURN_THROWS();
}
ciphertext_len = msg_len;
ciphertext = zend_string_checked_alloc((size_t) ciphertext_len, 0);
if (crypto_stream_xchacha20_xor_ic((unsigned char *) ZSTR_VAL(ciphertext), msg,
(unsigned long long) msg_len, nonce,
(unsigned long long) ic, key) != 0) {
zend_string_free(ciphertext);
zend_throw_exception(sodium_exception_ce, "internal error", 0);
RETURN_THROWS();
}
ZSTR_VAL(ciphertext)[ciphertext_len] = 0;

RETURN_NEW_STR(ciphertext);
}
#endif

#ifdef crypto_pwhash_SALTBYTES
Expand Down
2 changes: 2 additions & 0 deletions ext/sodium/libsodium.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ function sodium_crypto_stream_xchacha20(int $length, string $nonce, string $key)
function sodium_crypto_stream_xchacha20_keygen(): string {}

function sodium_crypto_stream_xchacha20_xor(string $message, string $nonce, string $key): string {}

function sodium_crypto_stream_xchacha20_xor_ic(string $message, string $nonce, int $counter, string $key): string {}
#endif

function sodium_add(string &$string1, string $string2): void {}
Expand Down
15 changes: 15 additions & 0 deletions ext/sodium/libsodium_arginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_stream_xchacha20_x
ZEND_END_ARG_INFO()
#endif

#if defined(crypto_stream_xchacha20_KEYBYTES)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_stream_xchacha20_xor_ic, 0, 4, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, nonce, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, counter, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0)
ZEND_END_ARG_INFO()
#endif

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_add, 0, 2, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(1, string1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, string2, IS_STRING, 0)
Expand Down Expand Up @@ -662,6 +671,9 @@ ZEND_FUNCTION(sodium_crypto_stream_xchacha20_keygen);
#if defined(crypto_stream_xchacha20_KEYBYTES)
ZEND_FUNCTION(sodium_crypto_stream_xchacha20_xor);
#endif
#if defined(crypto_stream_xchacha20_KEYBYTES)
ZEND_FUNCTION(sodium_crypto_stream_xchacha20_xor_ic);
#endif
ZEND_FUNCTION(sodium_add);
ZEND_FUNCTION(sodium_compare);
ZEND_FUNCTION(sodium_increment);
Expand Down Expand Up @@ -844,6 +856,9 @@ static const zend_function_entry ext_functions[] = {
#endif
#if defined(crypto_stream_xchacha20_KEYBYTES)
ZEND_FE(sodium_crypto_stream_xchacha20_xor, arginfo_sodium_crypto_stream_xchacha20_xor)
#endif
#if defined(crypto_stream_xchacha20_KEYBYTES)
ZEND_FE(sodium_crypto_stream_xchacha20_xor_ic, arginfo_sodium_crypto_stream_xchacha20_xor_ic)
#endif
ZEND_FE(sodium_add, arginfo_sodium_add)
ZEND_FE(sodium_compare, arginfo_sodium_compare)
Expand Down
18 changes: 18 additions & 0 deletions ext/sodium/tests/crypto_stream_xchacha20.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ $stream6 = sodium_crypto_stream_xchacha20_xor($stream5, $nonce, $key);

var_dump($stream6 === $stream);

// New test (with Initial Counter feature):
$n2 = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);
$left = str_repeat("\x01", 64);
$right = str_repeat("\xfe", 64);

// All at once:
$stream7_unified = sodium_crypto_stream_xchacha20_xor($left . $right, $n2, $key);

// Piecewise, with initial counter:
$stream7_left = sodium_crypto_stream_xchacha20_xor_ic($left, $n2, 0, $key);
$stream7_right = sodium_crypto_stream_xchacha20_xor_ic($right, $n2, 1, $key);
$stream7_concat = $stream7_left . $stream7_right;

var_dump(strlen($stream7_concat));
var_dump($stream7_unified === $stream7_concat);

try {
sodium_crypto_stream_xchacha20(-1, $nonce, $key);
} catch (SodiumException $ex) {
Expand Down Expand Up @@ -71,6 +87,8 @@ bool(true)
bool(true)
bool(true)
bool(true)
int(128)
bool(true)
sodium_crypto_stream_xchacha20(): Argument #1 ($length) must be greater than 0
sodium_crypto_stream_xchacha20(): Argument #2 ($nonce) must be SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES bytes long
sodium_crypto_stream_xchacha20(): Argument #3 ($key) must be SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES bytes long
Expand Down