MODULE = Crypt::Sodium::XS PACKAGE = Crypt::Sodium::XS::shorthash
void _define_constants()
PREINIT:
HV *stash = gv_stashpv("Crypt::Sodium::XS::shorthash", 0);
PPCODE:
newCONSTSUB(stash, "shorthash_BYTES", newSVuv(crypto_shorthash_BYTES));
newCONSTSUB(stash, "shorthash_siphash24_BYTES",
newSVuv(crypto_shorthash_siphash24_BYTES));
newCONSTSUB(stash, "shorthash_siphashx24_BYTES",
newSVuv(crypto_shorthash_siphashx24_BYTES));
newCONSTSUB(stash, "shorthash_KEYBYTES", newSVuv(crypto_shorthash_KEYBYTES));
newCONSTSUB(stash, "shorthash_siphash24_KEYBYTES",
newSVuv(crypto_shorthash_siphash24_KEYBYTES));
newCONSTSUB(stash, "shorthash_siphashx24_KEYBYTES",
newSVuv(crypto_shorthash_siphashx24_KEYBYTES));
newCONSTSUB(stash, "shorthash_PRIMITIVE",
newSVpvs(crypto_shorthash_PRIMITIVE));
SV * shorthash(SV * msg, SV * key)
ALIAS:
shorthash_siphash24 = 1
shorthash_siphashx24 = 2
PREINIT:
protmem *key_mv = NULL;
unsigned char *msg_buf;
unsigned char *key_buf;
unsigned char *out_buf;
STRLEN msg_len;
STRLEN key_len;
STRLEN key_req_len;
STRLEN out_len;
int (*func)(unsigned char *, const unsigned char *,
unsigned long long, const unsigned char *);
CODE:
switch(ix) {
case 1:
key_req_len = crypto_shorthash_siphash24_KEYBYTES;
out_len = crypto_shorthash_siphash24_BYTES;
func = crypto_shorthash_siphash24;
break;
case 2:
key_req_len = crypto_shorthash_siphashx24_KEYBYTES;
out_len = crypto_shorthash_siphashx24_BYTES;
func = crypto_shorthash_siphashx24;
break;
default:
key_req_len = crypto_shorthash_KEYBYTES;
out_len = crypto_shorthash_BYTES;
func = crypto_shorthash;
}
if (sv_derived_from(key, MEMVAULT_CLASS)) {
key_mv = protmem_get(aTHX_ key, MEMVAULT_CLASS);
key_buf = key_mv->pm_ptr;
key_len = key_mv->size;
}
else
key_buf = (unsigned char *)SvPVbyte(key, key_len);
if (key_len != key_req_len)
croak("shorthash: Invalid key length %lu", key_len);
msg_buf = (unsigned char *)SvPVbyte(msg, msg_len);
Newx(out_buf, out_len + 1, unsigned char);
if (out_buf == NULL)
croak("shorthash: Failed to allocate memory");
out_buf[out_len] = '\0';
if (key_mv && protmem_grant(aTHX_ key_mv, PROTMEM_FLAG_MPROTECT_RO) != 0) {
Safefree(out_buf);
croak("shorthash: Failed to grant key protmem RO");
}
func(out_buf, msg_buf, msg_len, key_buf);
if (key_mv && protmem_release(aTHX_ key_mv, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("shorthash: Failed to release key protmem RO");
RETVAL = newSV(0);
sv_usepvn_flags(RETVAL, (char *)out_buf, out_len, SV_HAS_TRAILING_NUL);
OUTPUT:
RETVAL
SV * shorthash_keygen(SV * flags = &PL_sv_undef)
ALIAS:
shorthash_siphash24_keygen = 1
shorthash_siphashx24_keygen = 2
CODE:
switch(ix) {
case 1:
RETVAL = sv_keygen(aTHX_ crypto_shorthash_siphash24_KEYBYTES, flags);
break;
case 2:
RETVAL = sv_keygen(aTHX_ crypto_shorthash_siphashx24_KEYBYTES, flags);
break;
default:
RETVAL = sv_keygen(aTHX_ crypto_shorthash_KEYBYTES, flags);
}
OUTPUT:
RETVAL