Skip to content

Commit

Permalink
Merge pull request #12 from starbelly/xchacha
Browse files Browse the repository at this point in the history
Merging starbelly's patch as is, will rebase my local version.

> crypto_aead_xchacha20poly1305_ietf_* support
  • Loading branch information
mgregoro committed Apr 18, 2018
2 parents 7d465a6 + f901baa commit ccc0173
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
90 changes: 90 additions & 0 deletions Sodium.xs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,22 @@ crypto_pwhash_ALG_ARGON2I13()
OUTPUT:
RETVAL

SV *
crypto_aead_xchacha20poly1305_ietf_KEYBYTES()
CODE:
RETVAL = newSVuv((unsigned int) crypto_aead_xchacha20poly1305_ietf_KEYBYTES);

OUTPUT:
RETVAL

SV *
crypto_aead_xchacha20poly1305_ietf_NPUBBYTES()
CODE:
RETVAL = newSVuv((unsigned int) crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);

OUTPUT:
RETVAL

SV *
real_sodium_init()
CODE:
Expand Down Expand Up @@ -914,3 +930,77 @@ real_crypto_pwhash_scrypt_str_verify(hp, p)

OUTPUT:
RETVAL

SV *
real_crypto_aead_xchacha20poly1305_ietf_keygen()
CODE:
unsigned char key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES];
crypto_aead_xchacha20poly1305_ietf_keygen(key);
RETVAL = newSVpvn((unsigned char *)key, sizeof(key));
OUTPUT:
RETVAL

SV *
real_crypto_aead_xchacha20poly1305_ietf_encrypt(m, mlen, ad, adlen, nsec, k)
unsigned char *m
unsigned long mlen
unsigned char *ad
unsigned long adlen
unsigned char *nsec
unsigned char *k

CODE:
unsigned char ciphertext[mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES];
unsigned long long ciphertext_len;

int status = crypto_aead_xchacha20poly1305_ietf_encrypt(
ciphertext,
&ciphertext_len,
(const unsigned char*)m,
(unsigned long long) mlen,
(const unsigned char*)ad,
(unsigned long long) adlen,
NULL,
(unsigned char *)nsec,
(unsigned char *)k
);

if (status == 0) {
RETVAL = newSVpvn((unsigned char *)ciphertext, ciphertext_len);
} else {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL

SV *
real_crypto_aead_xchacha20poly1305_ietf_decrypt(c, clen, ad, adlen, npub, k)
unsigned char *c
unsigned long clen
unsigned char *k
unsigned char *ad
unsigned long adlen
unsigned char *npub

CODE:
unsigned char m[clen - crypto_aead_xchacha20poly1305_ietf_ABYTES];
unsigned long long mlen;
int status = crypto_aead_xchacha20poly1305_ietf_decrypt(
m,
&mlen,
NULL,
(const unsigned char*)c,
(unsigned long long)clen,
(const unsigned char*)ad,
(unsigned long long) adlen,
(const unsigned char*)npub,
(const unsigned char*)k
);

if (status == 0) {
RETVAL = newSVpvn((unsigned char *)m, mlen);
} else {
RETVAL = &PL_sv_undef;
}
OUTPUT:
RETVAL
65 changes: 64 additions & 1 deletion lib/Crypt/Sodium.pm
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ our @EXPORT = qw/
crypto_pwhash
crypto_pwhash_str
crypto_pwhash_str_verify
crypto_aead_xchacha20poly1305_ietf_nonce
crypto_aead_xchacha20poly1305_ietf_keygen
crypto_aead_xchacha20poly1305_ietf_encrypt
crypto_aead_xchacha20poly1305_ietf_decrypt
randombytes_buf
randombytes_random
randombytes_uniform
Expand Down Expand Up @@ -120,6 +123,8 @@ our @EXPORT = qw/
crypto_pwhash_STRBYTES
crypto_pwhash_ALG_DEFAULT
crypto_pwhash_ALG_ARGON2I13
crypto_aead_xchacha20poly1305_ietf_KEYBYTES
crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
/;

use subs qw/
Expand Down Expand Up @@ -171,6 +176,8 @@ use subs qw/
crypto_pwhash_STRBYTES
crypto_pwhash_ALG_DEFAULT
crypto_pwhash_ALG_ARGON2I13
crypto_aead_xchacha20poly1305_ietf_KEYBYTES
crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
/;


Expand Down Expand Up @@ -522,6 +529,29 @@ sub crypto_pwhash_scrypt_str_verify {
return real_crypto_pwhash_scrypt_str_verify($hashed_pass, $pass);
}

sub crypto_aead_xchacha20poly1305_ietf_nonce {

return randombytes_buf(crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
}

sub crypto_aead_xchacha20poly1305_ietf_keygen {
my ($message, $ad, $nonce, $key) = @_;

return real_crypto_aead_xchacha20poly1305_ietf_keygen();
}

sub crypto_aead_xchacha20poly1305_ietf_encrypt {
my ($message, $ad, $nonce, $key) = @_;

return real_crypto_aead_xchacha20poly1305_ietf_encrypt($message, length($message), $ad, length($ad), $nonce, $key);
}

sub crypto_aead_xchacha20poly1305_ietf_decrypt {
my ($cipher, $ad, $nonce, $key) = @_;

return real_crypto_aead_xchacha20poly1305_ietf_decrypt($cipher, length($cipher), $ad, length($ad), $nonce, $key);
}

# Preloaded methods go here.

1;
Expand Down Expand Up @@ -708,6 +738,37 @@ Crypt::Sodium - Perl bindings for libsodium (NaCL) https://github.com/jedisct1/l
Note: The shared secret generated is a hash of the output of crypto_scalarmult xor'd with the two public
keys as outlined here L<https://download.libsodium.org/doc/advanced/scalar_multiplication.html>.
=item crypto_aead_xchacha20poly1305_ietf_keygen()
Usage: my $key = crypto_aead_xchacha20poly1305_ietf_keygen();
Note: This helper function is equivalent to calling randombytes_buf(crypto_aead_xchacha20poly1305_KEYBYTES)
See L<https://download.libsodium.org/doc/secret-key_cryptography/xchacha20-poly1305_construction.html> for details>.
=item crypto_aead_xchacha20poly1305_ietf_nonce()
Usage: my $key = crypto_aead_xchacha20poly1305_ietf_nonce();
Note: This helper function is equivalent to calling randombytes_buf(crypto_aead_xchacha20poly1305_NPUBBYTES)
See L<https://download.libsodium.org/doc/secret-key_cryptography/xchacha20-poly1305_construction.html> for details>.
=item crypto_aead_xchacha20poly1305_ietf_encrypt($message, $ad, $nonce, $key)
Usage: my $ciphered = crypto_aead_xchacha20poly1305_ietf_encrypt($message, $ad, $nonce, $key);
Example: my $k = crypto_aead_xchacha20poly1305_ietf_keygen();
my $n = crypto_aead_xchacha20poly1305_ietf_nonce();
my $ciphered = crypto_aead_xchacha20poly1305_ietf_encrypt("secret", "additional data", $n, $k);
Note: See L<https://download.libsodium.org/doc/secret-key_cryptography/xchacha20-poly1305_construction.html> for details>.
=item crypto_aead_xchacha20poly1305_ietf_decrypt($ciphered, $ad, $nonce, $key)
Usage: my $ciphered = crypto_aead_xchacha20poly1305_ietf_encrypt($ciphered, $ad, $nonce, $key)
Note: See L<https://download.libsodium.org/doc/secret-key_cryptography/xchacha20-poly1305_construction.html> for details>.
=back
=head1 EXPORTED CONSTANTS
Expand All @@ -728,6 +789,8 @@ Crypt::Sodium - Perl bindings for libsodium (NaCL) https://github.com/jedisct1/l
crypto_pwhash_OPSLIMIT
crypto_pwhash_MEMLIMIT
crypto_pwhash_STRBYTES
crypto_aead_xchacha20poly1305_KEYBYTES
crypto_aead_xchacha20poly1305_NPUBBYTES
=head1 SEE ALSO
Expand Down
11 changes: 11 additions & 0 deletions t/Crypt-Sodium.t
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,16 @@ ok(length($ahashed) == crypto_pwhash_STRBYTES, "returned a string crypto_pwhash_
ok(crypto_pwhash_str_verify($ahashed, 'Ultra Secret Fantastico'), 'password verification succeeded, moderate-difficulty hash');
ok(!crypto_pwhash_str_verify($ahashed, 'Ultra Secretish Fantastico'), 'password verification failed on bad password, moderate difficulty');

# xchacha/poly1035
ok(my $xchacha_key = crypto_aead_xchacha20poly1305_ietf_keygen());
ok(length($xchacha_key) == crypto_aead_xchacha20poly1305_ietf_KEYBYTES, "returned a string crypto_aead_xchacha20poly1305_ietf_KEYBYTES in length");
ok(my $xchacha_nonce = crypto_aead_xchacha20poly1305_ietf_nonce());
ok(length($xchacha_nonce) == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES, "returned a string crypto_aead_xchacha20poly1305_ietf_NPUBBYTES in length");
ok(my $ciphered = crypto_aead_xchacha20poly1305_ietf_encrypt("1234", "additional data", $xchacha_nonce, $xchacha_key), "xchacha/poly1035 encryption succeeded");
ok(crypto_aead_xchacha20poly1305_ietf_decrypt($ciphered, "additional data", $xchacha_nonce, $xchacha_key) eq "1234", "xchacha/poly1035 decryption succeeded");
ok(!crypto_aead_xchacha20poly1305_ietf_decrypt($ciphered, "wrong data", $xchacha_nonce, $xchacha_key), "xchacha/poly1035 decryption failed with bad AD");
ok(!crypto_aead_xchacha20poly1305_ietf_decrypt($ciphered, "additional data", "Wrong Nonce", $xchacha_key), "xchacha/poly1035 decryption failed with bad nonce");
ok(!crypto_aead_xchacha20poly1305_ietf_decrypt($ciphered, "additional data", $xchacha_nonce, "Wrong key"), "xchacha/poly1035 decryption failed with bad key");

done_testing();

0 comments on commit ccc0173

Please sign in to comment.