Crypt-Sodium-XS
view release on metacpan or search on metacpan
inc/secretbox.xs view on Meta::CPAN
=for documentation
similar to the situation with kx, libsodium does not have separate secretbox
functions for xsalsa20poly1305 _easy, _detached, _open_easy, or _open_detached.
it is the default algorithm for them. aliases are still provided, and just fall
through to the defaults.
=cut
MODULE = Crypt::Sodium::XS PACKAGE = Crypt::Sodium::XS::secretbox
void _define_constants()
PREINIT:
HV *stash = gv_stashpv("Crypt::Sodium::XS::secretbox", 0);
PPCODE:
newCONSTSUB(stash, "secretbox_KEYBYTES", newSVuv(crypto_secretbox_KEYBYTES));
newCONSTSUB(stash, "secretbox_xchacha20poly1305_KEYBYTES",
newSVuv(crypto_secretbox_xchacha20poly1305_KEYBYTES));
newCONSTSUB(stash, "secretbox_xsalsa20poly1305_KEYBYTES",
newSVuv(crypto_secretbox_xsalsa20poly1305_KEYBYTES));
newCONSTSUB(stash, "secretbox_MACBYTES", newSVuv(crypto_secretbox_MACBYTES));
newCONSTSUB(stash, "secretbox_xchacha20poly1305_MACBYTES",
newSVuv(crypto_secretbox_xchacha20poly1305_MACBYTES));
newCONSTSUB(stash, "secretbox_xsalsa20poly1305_MACBYTES",
newSVuv(crypto_secretbox_xsalsa20poly1305_MACBYTES));
newCONSTSUB(stash, "secretbox_NONCEBYTES",
newSVuv(crypto_secretbox_NONCEBYTES));
newCONSTSUB(stash, "secretbox_xchacha20poly1305_NONCEBYTES",
newSVuv(crypto_secretbox_xchacha20poly1305_NONCEBYTES));
newCONSTSUB(stash, "secretbox_xsalsa20poly1305_NONCEBYTES",
newSVuv(crypto_secretbox_xsalsa20poly1305_NONCEBYTES));
newCONSTSUB(stash, "secretbox_PRIMITIVE", newSVpvs(crypto_secretbox_PRIMITIVE));
SV * secretbox_decrypt( \
SV * ciphertext, \
SV * nonce, \
SV * key, \
SV * flags = &PL_sv_undef \
)
ALIAS:
secretbox_xchacha20poly1305_decrypt = 1
secretbox_xsalsa20poly1305_decrypt = 2
PREINIT:
protmem *msg_pm, *key_pm = NULL;
unsigned char *ct_buf, *nonce_buf, *key_buf;
STRLEN ct_len, nonce_len, key_len, nonce_req_len, key_req_len, mac_len;
unsigned int msg_flags = g_protmem_default_flags_decrypt;
int ret;
int (*func)(unsigned char *, const unsigned char *,
unsigned long long, const unsigned char *,
const unsigned char *);
CODE:
switch(ix) {
case 1:
nonce_req_len = crypto_secretbox_xchacha20poly1305_NONCEBYTES;
key_req_len = crypto_secretbox_xchacha20poly1305_KEYBYTES;
mac_len = crypto_secretbox_xchacha20poly1305_MACBYTES;
func = crypto_secretbox_xchacha20poly1305_open_easy;
break;
case 2: /* fallthrough */
default:
nonce_req_len = crypto_secretbox_NONCEBYTES;
key_req_len = crypto_secretbox_KEYBYTES;
mac_len = crypto_secretbox_MACBYTES;
func = crypto_secretbox_open_easy;
}
SvGETMAGIC(flags);
if (SvOK(flags))
msg_flags = SvUV_nomg(flags);
ct_buf = (unsigned char *)SvPVbyte(ciphertext, ct_len);
inc/secretbox.xs view on Meta::CPAN
key_buf = key_pm->pm_ptr;
key_len = key_pm->size;
}
else
key_buf = (unsigned char *)SvPVbyte(key, key_len);
if (key_len != key_req_len)
croak("secretbox_decrypt_detached: Invalid key length: %lu", key_len);
msg_pm = protmem_init(aTHX_ ct_len, msg_flags);
if (msg_pm == NULL)
croak("secretbox_decrypt_detached: Failed to allocate protmem");
if (key_pm && protmem_grant(aTHX_ key_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ msg_pm);
croak("secretbox_decrypt_detached: Failed to grant key protmem RO");
}
ret = func(msg_pm->pm_ptr, ct_buf, mac_buf, ct_len, nonce_buf, key_buf);
if (key_pm && protmem_release(aTHX_ key_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ msg_pm);
croak("secretbox_decrypt_detached: Failed to release key protmem RO");
}
if (protmem_release(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ msg_pm);
croak("secretbox_decrypt_detached: Failed to release msg protmem RO");
}
if (ret == 0)
RETVAL = protmem_to_sv(aTHX_ msg_pm, MEMVAULT_CLASS);
else {
protmem_free(aTHX_ msg_pm);
croak("secretbox_decrypt_detached: Message forged");
}
OUTPUT:
RETVAL
void secretbox_encrypt(SV * msg, SV * nonce, SV * key)
ALIAS:
secretbox_encrypt_detached = 1
secretbox_xchacha20poly1305_encrypt = 2
secretbox_xchacha20poly1305_encrypt_detached = 3
secretbox_xsalsa20poly1305_encrypt = 4
secretbox_xsalsa20poly1305_encrypt_detached = 5
PREINIT:
protmem *key_pm = NULL, *msg_mv = NULL;
SV *ct, *mac = NULL;
unsigned char *msg_buf, *nonce_buf, *key_buf, *ct_buf, *mac_buf;
STRLEN msg_len, nonce_len, key_len, nonce_req_len, key_req_len, mac_len;
int (*detached_func)(unsigned char *, unsigned char *,
const unsigned char *, unsigned long long,
const unsigned char *, const unsigned char *);
int (*easy_func)(unsigned char *, const unsigned char *,
unsigned long long, const unsigned char *,
const unsigned char *);
PPCODE:
switch(ix) {
case 2:
case 3: /* fallthrough */
nonce_req_len = crypto_secretbox_xchacha20poly1305_NONCEBYTES;
key_req_len = crypto_secretbox_xchacha20poly1305_KEYBYTES;
mac_len = crypto_secretbox_xchacha20poly1305_MACBYTES;
detached_func = crypto_secretbox_xchacha20poly1305_detached;
easy_func = crypto_secretbox_xchacha20poly1305_easy;
break;
case 4: /* fallthrough */
case 5: /* fallthrough */
case 1: /* fallthrough */
default:
nonce_req_len = crypto_secretbox_NONCEBYTES;
key_req_len = crypto_secretbox_KEYBYTES;
mac_len = crypto_secretbox_MACBYTES;
detached_func = crypto_secretbox_detached;
easy_func = crypto_secretbox_easy;
}
nonce_buf = (unsigned char *)SvPVbyte(nonce, nonce_len);
if (nonce_len != nonce_req_len)
croak("secretbox_encrypt: Invalid nonce length %lu", nonce_len);
if (sv_derived_from(key, MEMVAULT_CLASS)) {
key_pm = protmem_get(aTHX_ key, MEMVAULT_CLASS);
key_buf = key_pm->pm_ptr;
key_len = key_pm->size;
}
else
key_buf = (unsigned char *)SvPVbyte(key, key_len);
if (key_len != key_req_len)
croak("secretbox_encrypt: Invalid key length %lu", key_len);
if (sv_derived_from(msg, MEMVAULT_CLASS)) {
msg_mv = protmem_get(aTHX_ msg, MEMVAULT_CLASS);
msg_buf = msg_mv->pm_ptr;
msg_len = msg_mv->size;
}
else
msg_buf = (unsigned char *)SvPVbyte(msg, msg_len);
if (key_pm && protmem_grant(aTHX_ key_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("secretbox_encrypt: Failed to grant key protmem RO");
if (msg_mv && protmem_grant(aTHX_ msg_mv, PROTMEM_FLAG_MPROTECT_RO) != 0) {
if (key_pm)
protmem_release(aTHX_ key_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("secretbox_encrypt: Failed to grant msg protmem RO");
}
/* NB: odd aliases are _detached, even are combined */
if (ix & 1) {
/* detached mode */
Newx(mac_buf, mac_len + 1, unsigned char);
if (mac_buf == NULL) {
if (key_pm)
protmem_release(aTHX_ key_pm, PROTMEM_FLAG_MPROTECT_RO);
if (msg_mv)
protmem_release(aTHX_ msg_mv, PROTMEM_FLAG_MPROTECT_RO);
( run in 0.726 second using v1.01-cache-2.11-cpan-71847e10f99 )