Crypt-Sodium-XS
view release on metacpan or search on metacpan
inc/memvault.xs view on Meta::CPAN
tattr.c_lflag |= ICANON | ISIG;
tattr.c_lflag &= ~ECHO;
if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) {
write(fd, "\n", 1);
protmem_free(aTHX_ new_pm);
croak("new_from_ttyno: Failed tcsetattr");
}
tattr.c_lflag = lflag_prev; /* prepared for next tcsetattr to reset */
for (;;) {
r = read(fd, new_pm->pm_ptr, 4096);
if (r < 0) {
if (errno == EINTR)
continue;
write(fd, "\n", 1);
protmem_free(aTHX_ new_pm);
tcsetattr(fd, TCSAFLUSH, &tattr);
croak("new_from_ttyno: Failed read");
}
else
break;
}
if (r == 0)
write(fd, " (WARNING: empty)", (sizeof " (WARNING: empty)" - 1));
else if (*((unsigned char *)new_pm->pm_ptr + r - 1) == '\n')
r -= 1;
else if (*((unsigned char *)new_pm->pm_ptr + r - 1) == '\r')
r -= 1;
else if (r == 4096)
write(fd, " (WARNING: truncated to 4096 bytes)",
(sizeof " (WARNING: truncated to 4096 bytes)" - 1));
new_pm->size = r;
write(fd, "\n", 1);
if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) {
protmem_free(aTHX_ new_pm);
croak("new_from_ttyno: tcsetattr failed");
}
RETVAL = protmem_to_sv(aTHX_ new_pm, class);
OUTPUT:
RETVAL
void DESTROY(SV * self)
PREINIT:
protmem *self_pm;
CODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
protmem_free(aTHX_ self_pm);
void _overload_bool(SV * self, ...)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (self_pm->size)
XSRETURN_YES;
else
XSRETURN_NO;
SV * _overload_mult(SV * self, SV * other, SV * swapped)
PREINIT:
protmem *self_pm;
protmem *new_pm;
unsigned int count = 0;
unsigned int cur = 0;
CODE:
PERL_UNUSED_VAR(swapped);
count = SvUV(other);
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
new_pm = protmem_init(aTHX_ self_pm->size * count, self_pm->flags);
if (new_pm == NULL)
croak("_overload_mult: Failed to allocate protmem");
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("_overload_mult: Failed to grant self protmem RO");
while(count--)
memcpy(new_pm->pm_ptr + self_pm->size * cur++, self_pm->pm_ptr, self_pm->size);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ new_pm);
croak("_overload_mult: Failed to release self protmem RO");
}
if (protmem_release(aTHX_ new_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ new_pm);
croak("_overload_mult: Failed to release new protmem RW");
}
RETVAL = protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
void _overload_nomethod(SV * self, ...)
PREINIT:
char *operator;
PPCODE:
PERL_UNUSED_VAR(self);
operator = SvPVbyte_nolen(ST(3));
croak("Operation \"%s\" on MemVault is not supported", operator);
void bitwise_and(SV * self, SV * other, ...)
ALIAS:
bitwise_or = 1
bitwise_xor = 2
bitwise_and_equals = 100
bitwise_or_equals = 101
bitwise_xor_equals = 102
PREINIT:
protmem *self_pm;
protmem *other_pm = NULL;
protmem *new_pm = NULL;
unsigned char *buf;
unsigned char *other_buf;
STRLEN other_len;
STRLEN i;
unsigned int new_flags;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (sv_derived_from(other, MEMVAULT_CLASS)) {
other_pm = protmem_get(aTHX_ other, MEMVAULT_CLASS);
other_buf = other_pm->pm_ptr;
other_len = other_pm->size;
}
else
other_buf = (unsigned char *)SvPVbyte(other, other_len);
if (other_len != self_pm->size)
/* lengths MUST be identical below */
croak("Exclusive-or operands do not have equal length");
if (ix >= 100) {
if (other_pm)
if (protmem_grant(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("xor: Failed to grant other protmem RO");
}
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("xor: Failed to grant self protmem RW");
}
buf = self_pm->pm_ptr;
/* lengths identical, assured above */
for (i = 0; i < other_len; i++)
switch(ix) {
case 101:
buf[i] |= other_buf[i];
break;
case 102:
buf[i] ^= other_buf[i];
break;
default: /* 100 */
buf[i] &= other_buf[i];
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("xor: Failed to release self protmem RW");
}
}
else {
new_flags = self_pm->flags;
if (other_pm)
new_flags &= other_pm->flags;
new_pm = protmem_init(aTHX_ self_pm->size, new_flags);
if (new_pm == NULL)
croak("xor: Failed to allocate protmem");
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("xor: Failed to grant self protmem RO");
if (other_pm)
if (protmem_grant(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("xor: Failed to grant other protmem RO");
}
buf = memcpy(new_pm->pm_ptr, self_pm->pm_ptr, self_pm->size);
for (i = 0; i < other_len; i++)
switch(ix) {
case 1:
buf[i] |= other_buf[i];
break;
case 2:
buf[i] ^= other_buf[i];
break;
default:
buf[i] &= other_buf[i];
}
if (protmem_release(aTHX_ new_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("xor: Failed to release new protmem RW");
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("xor: Failed to release self protmem RW");
}
mXPUSHs(protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS));
}
if (other_pm)
if (protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("xor: Failed to release other protmem RO");
XSRETURN(1);
SV * clone(SV * self)
CODE:
RETVAL = protmem_clone_sv(aTHX_ self, MEMVAULT_CLASS);
OUTPUT:
RETVAL
void compare(SV * self, SV * other, STRLEN size = 0)
ALIAS:
_overload_eq = 1
_overload_ne = 2
memcmp = 3
PREINIT:
protmem *self_pm = NULL, *other_pm = NULL;
unsigned char *self_buf, *other_buf;
STRLEN self_size, other_size;
int ret = 0;
PPCODE:
/* since used for overloads, args could be swapped. could require either self
* or other to be a memvault */
if (sv_derived_from(self, MEMVAULT_CLASS)) {
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (ix == 0 && !(self_pm->flags & PROTMEM_FLAG_LOCK_UNLOCKED))
croak("compare: Unlock MemVault object before comparison");
self_buf = self_pm->pm_ptr;
self_size = self_pm->size;
}
else
self_buf = (unsigned char *)SvPVbyte(self, self_size);
if (sv_derived_from(other, MEMVAULT_CLASS)) {
other_pm = protmem_get(aTHX_ other, MEMVAULT_CLASS);
if (ix == 0 && !(other_pm->flags & PROTMEM_FLAG_LOCK_UNLOCKED))
croak("compare: Unlock MemVault object before comparison");
other_buf = other_pm->pm_ptr;
other_size = other_pm->size;
}
else
other_buf = (unsigned char *)SvPVbyte(other, other_size);
if (self_size != other_size) {
switch(ix) {
case 1: /* fallthrough */
case 2:
croak("compare: %s %s",
"Variables of unequal size cannot be automatically compared.",
"Please use memcmp() with the size argument provided.");
break;
default:
if (size == 0) {
croak("compare: %s %s",
"Variables of unequal size cannot be automatically compared.",
"Please provide the size argument.");
}
else {
if (size > self_size)
croak("compare: The argument (left) is shorter then requested size");
else if (size > other_size)
croak("compare: The argument (right) is shorter then requested size");
}
}
}
if (self_pm)
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("compare: Failed to grant self protmem RO");
if (other_pm) {
if (protmem_grant(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
if (self_pm)
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("compare: Failed to grant other protmem RO");
}
}
if (ix != 0)
ret = sodium_memcmp(self_buf, other_buf, self_size);
else
ret = sodium_compare(self_buf, other_buf, self_size);
if (other_pm && protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
if (self_pm)
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("compare: Failed to release other protmem RO");
}
if (self_pm && protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("compare: Failed to release self protmem RO");
if (ix == 0) {
XSRETURN_IV(ret);
}
else if (ix == 2) {
if (ret == 0)
XSRETURN_NO;
XSRETURN_YES;
}
else {
if (ret == 0)
XSRETURN_YES;
XSRETURN_NO;
}
=for TODO
consider a flags argument. that cannot co-exist with overloading as it is now.
=cut
void concat(SV * self, SV * other, SV * swapped = &PL_sv_undef)
ALIAS:
concat_inplace = 1
PREINIT:
protmem *self_pm;
protmem *other_pm = NULL;
protmem *new_pm;
unsigned char *buf;
MAGIC *mg, *mg_found=NULL;
STRLEN buf_len;
unsigned int new_flags;
PPCODE:
if (sv_derived_from(other, MEMVAULT_CLASS)) {
other_pm = protmem_get(aTHX_ other, MEMVAULT_CLASS);
buf = other_pm->pm_ptr;
buf_len = other_pm->size;
}
else
buf = (unsigned char *)SvPVbyte(other, buf_len);
/* should probably zero buf afterwards */
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
new_flags = self_pm->flags;
if (other_pm)
new_flags &= other_pm->flags;
new_pm = protmem_init(aTHX_ self_pm->size + buf_len, new_flags);
if (new_pm == NULL)
croak("concat: Failed to allocate protmem");
if (other_pm && protmem_grant(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ new_pm);
croak("concat: Failed to grant other protmem RO");
}
if (ix == 0) {
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("concat: Failed to grant self protmem RO");
}
if (SvTRUE(swapped))
memcpy(memcpy(new_pm->pm_ptr, buf, buf_len) + buf_len,
self_pm->pm_ptr, self_pm->size);
else
memcpy(memcpy(new_pm->pm_ptr, self_pm->pm_ptr, self_pm->size)
+ self_pm->size, buf, buf_len);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("concat: Failed to release self protmem RO");
}
if (protmem_release(aTHX_ new_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("concat: Failed to release new protmem RW");
}
mXPUSHs(protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS));
}
else {
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
if (other_pm)
protmem_release(aTHX_ other_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("concat: Failed to grant self protmem RW");
}
inc/memvault.xs view on Meta::CPAN
protmem_free(aTHX_ new_pm);
croak("from_base64: Failed to release new protmem RW");
}
RETVAL = protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
SV * from_hex(SV * self, SV * flags = &PL_sv_undef)
PREINIT:
protmem *self_pm;
protmem *new_pm;
char *self_buf = NULL;
STRLEN self_len;
unsigned int new_flags = g_protmem_default_flags_memvault;
CODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
self_buf = (char *)self_pm->pm_ptr;
self_len = self_pm->size;
new_flags = self_pm->flags;
SvGETMAGIC(flags);
if (SvOK(flags))
new_flags = SvUV_nomg(flags);
new_pm = protmem_init(aTHX_ self_len / 2, new_flags);
if (new_pm == NULL)
croak("from_hex: Failed to allocate protmem");
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ new_pm);
croak("from_hex: Failed to grant self protmem RO");
}
sodium_hex2bin(new_pm->pm_ptr, new_pm->size, self_buf, self_len,
NULL, NULL, NULL);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ new_pm);
croak("from_hex: Failed to release self protmem RO");
}
if (protmem_release(aTHX_ new_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ new_pm);
croak("from_hex: Failed to release new protmem RW");
}
RETVAL = protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
void increment(SV * self)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("increment: Failed to grant self protmem RW");
sodium_increment(self_pm->pm_ptr, self_pm->size);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("increment: Failed to release self protmem RW");
XSRETURN(1);
SV * index(SV * self, SV * str, STRLEN offset = 0)
PREINIT:
protmem *self_pm;
char *str_buf;
unsigned char *self_start, *self_p, *self_stop;
STRLEN str_len;
CODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (!(self_pm->flags & PROTMEM_FLAG_LOCK_UNLOCKED))
croak("index: Unlock MemVault object before using index");
if (offset > self_pm->size - 1)
XSRETURN_IV(-1);
str_buf = SvPVbyte(str, str_len);
if (str_len < 1)
XSRETURN_IV(0);
self_start = (unsigned char *)self_pm->pm_ptr;
self_p = self_start + offset;
self_stop = self_start + self_pm->size - str_len; /* + 1 - 1 */
if (self_p >= self_stop)
XSRETURN_IV(-1);
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("index: Failed to grant self protmem RO");
RETVAL = &PL_sv_undef;
/* naive implementation, good nuff for "unsafe" */
while (self_p <= self_stop) {
if (*self_p == str_buf[0]) {
if (str_len == 1) {
RETVAL=newSVuv(self_p - self_start);
break;
}
else {
if (memcmp(self_p, str_buf, str_len) == 0) {
RETVAL = newSVuv(self_p - self_start);
break;
}
}
}
++self_p;
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("index: Failed to release self protmem RO");
OUTPUT:
RETVAL
void is_locked(SV * self)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (self_pm->flags & PROTMEM_FLAG_LOCK_UNLOCKED)
XSRETURN_NO;
XSRETURN_YES;
void is_zero(SV * self)
PREINIT:
protmem *self_pm;
int ret;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("is_zero: Failed to grant self protmem RO");
ret = sodium_is_zero(self_pm->pm_ptr, self_pm->size);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("is_zero: Failed to release self protmem RO");
if (ret)
XSRETURN_YES;
XSRETURN_NO;
SV * length(SV * self)
ALIAS:
size = 1
PREINIT:
protmem *self_pm;
CODE:
PERL_UNUSED_VAR(ix);
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
RETVAL = newSVuv((UV)self_pm->size);
OUTPUT:
RETVAL
void lock(SV * self)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
self_pm->flags &= ~PROTMEM_FLAG_LOCK_UNLOCKED;
XSRETURN(1);
SV * pad(SV * self, STRLEN blocksize)
PREINIT:
protmem *self_pm, *realloc_pm;
STRLEN buf_len, pad_len, padded_len;
CODE:
if (blocksize <= 0)
croak("pad: Invalid blocksize <= 0");
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
buf_len = self_pm->size;
pad_len = blocksize - 1;
if ((blocksize & (blocksize - 1)) == 0)
pad_len -= buf_len & (blocksize - 1);
else
pad_len -= buf_len % blocksize;
pad_len += 1; /* for 0x80 */
if ((STRLEN)SIZE_MAX - buf_len <= pad_len)
croak("pad: Pad exceeds SIZE_MAX");
padded_len = buf_len + pad_len;
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("pad: Failed to grant self protmem RO");
realloc_pm = protmem_clone(aTHX_ self_pm, padded_len);
if (realloc_pm == NULL) {
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("pad: Failed to allocate protmem");
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ realloc_pm);
croak("pad: Failed to release self protmem RO");
}
if (sodium_pad(&padded_len, realloc_pm->pm_ptr,
buf_len, blocksize, padded_len) != 0) {
/* should be impossible */
protmem_free(aTHX_ realloc_pm);
croak("BUG: pad: sodium_pad returned error");
}
if (protmem_release(aTHX_ realloc_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ realloc_pm);
croak("pad: Failed to release protmem RW");
}
RETVAL = protmem_to_sv(aTHX_ realloc_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
SV * to_base64( \
inc/memvault.xs view on Meta::CPAN
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ new_pm);
croak("to_hex: Failed to release new protmem RW");
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ new_pm);
croak("to_hex: Failed to release self protmem RO");
}
RETVAL = protmem_to_sv(aTHX_ new_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
SV * to_fd(SV * self, int fd)
PREINIT:
protmem *self_pm;
ssize_t w;
size_t t = 0;
size_t r = 0;
CODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) < 0)
croak("to_fd: Failed to grant self protmem RO");
/* w: current iteration written bytes */
/* t: total bytes written */
/* r: remaining bytes to write */
r = self_pm->size;
for (;;) {
w = write(fd, self_pm->pm_ptr + t,
r > MEMVAULT_WRITE_BUFSIZE ? MEMVAULT_WRITE_BUFSIZE : r);
if (w < 0) {
if (errno == EINTR)
continue;
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("to_fd: (%d): write error", fd);
}
t += w;
r -= w;
if (r == 0)
break;
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) < 0)
croak("to_fd: Failed to release self protmem RO");
RETVAL = newSVuv(t);
OUTPUT:
RETVAL
void unlock(SV * self)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
self_pm->flags |= PROTMEM_FLAG_LOCK_UNLOCKED;
XSRETURN(1);
SV * unpad(SV * self, STRLEN blocksize)
PREINIT:
protmem *self_pm, *realloc_pm;
STRLEN buf_len, unpadded_len;
CODE:
if (blocksize <= 0)
croak("unpad: Invalid blocksize <= 0");
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
buf_len = self_pm->size;
if (buf_len < blocksize)
croak("unpad: Buffer is shorter than blocksize");
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("unpad: Failed to grant self protmem RO");
if (sodium_unpad(&unpadded_len, self_pm->pm_ptr, self_pm->size, blocksize) != 0) {
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("unpad: Invalid padded buffer");
}
realloc_pm = protmem_clone(aTHX_ self_pm, unpadded_len);
if (realloc_pm == NULL) {
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("sodium_pad: Failed to allocate protmem");
}
if (protmem_release(aTHX_ realloc_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ realloc_pm);
protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("sodium_pad: Failed to release protmem RW");
}
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ realloc_pm);
croak("sodium_pad: Failed to release self protmem RO");
}
RETVAL = protmem_to_sv(aTHX_ realloc_pm, MEMVAULT_CLASS);
OUTPUT:
RETVAL
void memzero(SV * self)
PREINIT:
protmem *self_pm;
PPCODE:
self_pm = protmem_get(aTHX_ self, MEMVAULT_CLASS);
if (protmem_grant(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) < 0)
croak("memzero: Failed to grant self protmem RW");
sodium_memzero(self_pm->pm_ptr, self_pm->size);
if (protmem_release(aTHX_ self_pm, PROTMEM_FLAG_MPROTECT_RW) < 0)
croak("memzero: Failed to release self protmem RW");
=for FIXME
separate methods for xor (modify in place) from the overload (new
memvault). currently no explicit method for returning new memvault, only the
overload.
=cut
( run in 0.589 second using v1.01-cache-2.11-cpan-71847e10f99 )