Crypt-Sodium-XS
view release on metacpan or search on metacpan
inc/sign.xs view on Meta::CPAN
=for documentation
skipping sign_edwards25519sha512batch as it is not recommended. providing
aliases for sign_ed25519 as with other packages, though it is the default.
=cut
MODULE = Crypt::Sodium::XS PACKAGE = Crypt::Sodium::XS::sign
void _define_constants()
PREINIT:
HV *stash = gv_stashpv("Crypt::Sodium::XS::sign", 0);
PPCODE:
newCONSTSUB(stash, "sign_BYTES", newSVuv(crypto_sign_BYTES));
newCONSTSUB(stash, "sign_ed25519_BYTES", newSVuv(crypto_sign_ed25519_BYTES));
newCONSTSUB(stash, "sign_MESSAGEBYTES_MAX",
newSVuv(crypto_sign_MESSAGEBYTES_MAX));
newCONSTSUB(stash, "sign_ed25519_MESSAGEBYTES_MAX",
newSVuv(crypto_sign_ed25519_MESSAGEBYTES_MAX));
newCONSTSUB(stash, "sign_PUBLICKEYBYTES",
newSVuv(crypto_sign_PUBLICKEYBYTES));
newCONSTSUB(stash, "sign_ed25519_PUBLICKEYBYTES",
newSVuv(crypto_sign_ed25519_PUBLICKEYBYTES));
newCONSTSUB(stash, "sign_SECRETKEYBYTES",
newSVuv(crypto_sign_SECRETKEYBYTES));
newCONSTSUB(stash, "sign_ed25519_SECRETKEYBYTES",
newSVuv(crypto_sign_ed25519_SECRETKEYBYTES));
newCONSTSUB(stash, "sign_SEEDBYTES", newSVuv(crypto_sign_SEEDBYTES));
newCONSTSUB(stash, "sign_ed25519_SEEDBYTES",
newSVuv(crypto_sign_ed25519_SEEDBYTES));
newCONSTSUB(stash, "sign_PRIMITIVE", newSVpvs(crypto_sign_PRIMITIVE));
SV * sign(SV * msg, SV * sk)
ALIAS:
sign_ed25519 = 1
PREINIT:
protmem *msg_pm = NULL, *sk_pm = NULL;
unsigned char *msg_buf, *sk_buf, *smsg_buf;
STRLEN msg_len, sk_len, sk_req_len, sig_len, out_len;
int (*func)(unsigned char *, unsigned long long *, const unsigned char *,
unsigned long long, const unsigned char *);
CODE:
switch(ix) {
case 1:
sk_req_len = crypto_sign_ed25519_SECRETKEYBYTES;
sig_len = crypto_sign_ed25519_BYTES;
func = crypto_sign_ed25519;
break;
default:
sk_req_len = crypto_sign_SECRETKEYBYTES;
sig_len = crypto_sign_BYTES;
func = crypto_sign;
}
if (sv_derived_from(msg, MEMVAULT_CLASS)) {
msg_pm = protmem_get(aTHX_ msg, MEMVAULT_CLASS);
msg_buf = msg_pm->pm_ptr;
msg_len = msg_pm->size;
}
else
msg_buf = (unsigned char *)SvPVbyte(msg, msg_len);
if (SIZE_MAX - sig_len < msg_len)
croak("Message too large");
out_len = msg_len + sig_len;
if (sv_derived_from(sk, MEMVAULT_CLASS)) {
sk_pm = protmem_get(aTHX_ sk, MEMVAULT_CLASS);
sk_buf = sk_pm->pm_ptr;
sk_len = sk_pm->size;
inc/sign.xs view on Meta::CPAN
OUTPUT:
RETVAL
SV * sign_init(SV * flags = &PL_sv_undef)
ALIAS:
sign_ed25519_init = 1
PREINIT:
protmem *state_pm;
unsigned int state_flags = g_protmem_default_flags_state;
CODE:
SvGETMAGIC(flags);
if (SvOK(flags))
state_flags = SvUV_nomg(flags);
switch(ix) {
case 1:
state_pm = protmem_init(aTHX_ sizeof(crypto_sign_ed25519ph_state), state_flags);
if (state_pm == NULL)
croak("sign_init: Failed to allocate state protmem");
crypto_sign_ed25519ph_init(state_pm->pm_ptr);
break;
default:
state_pm = protmem_init(aTHX_ sizeof(crypto_sign_state), state_flags);
if (state_pm == NULL)
croak("sign_init: Failed to allocate state protmem");
crypto_sign_init(state_pm->pm_ptr);
}
if (protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ state_pm);
croak("sign_init: Failed to release state protmem RW");
}
switch(ix) {
case 1:
RETVAL = protmem_to_sv(aTHX_ state_pm, "Crypt::Sodium::XS::sign::ed25519ph_multi");
break;
default:
RETVAL = protmem_to_sv(aTHX_ state_pm, "Crypt::Sodium::XS::sign::multi"); }
OUTPUT:
RETVAL
void sign_keypair(SV * seed = &PL_sv_undef, SV * flags = &PL_sv_undef)
ALIAS:
sign_ed25519_keypair = 1
PREINIT:
protmem *seed_pm = NULL, *sk_pm;
SV *pk_sv;
unsigned char *pk_buf, *seed_buf;
STRLEN seed_req_len, seed_len;
STRLEN pk_len, sk_len;
unsigned int sk_flags = g_protmem_default_flags_key;
PPCODE:
SvGETMAGIC(flags);
if (SvOK(flags))
sk_flags = SvUV_nomg(flags);
switch(ix) {
case 1:
seed_req_len = crypto_sign_ed25519_SEEDBYTES;
pk_len = crypto_sign_ed25519_PUBLICKEYBYTES;
sk_len = crypto_sign_ed25519_SECRETKEYBYTES;
break;
default:
seed_req_len = crypto_sign_SEEDBYTES;
pk_len = crypto_sign_PUBLICKEYBYTES;
sk_len = crypto_sign_SECRETKEYBYTES;
}
Newx(pk_buf, pk_len + 1, unsigned char);
if (pk_buf == NULL)
croak("sign_keypair: Failed to allocate memory");
pk_buf[pk_len] = '\0';
SvGETMAGIC(seed);
if (!SvOK(seed)) {
sk_pm = protmem_init(aTHX_ sk_len, sk_flags);
if (sk_pm == NULL) {
Safefree(pk_buf);
croak("sign_keypair: Failed to allocate protmem");
}
switch(ix) {
case 1:
crypto_sign_ed25519_keypair(pk_buf, sk_pm->pm_ptr);
break;
default:
crypto_sign_keypair(pk_buf, sk_pm->pm_ptr);
}
}
else {
/* from seed */
if (sv_derived_from(seed, MEMVAULT_CLASS)) {
seed_pm = protmem_get(aTHX_ seed, MEMVAULT_CLASS);
seed_buf = seed_pm->pm_ptr;
seed_len = seed_pm->size;
}
else
seed_buf = (unsigned char *)SvPVbyte_nomg(seed, seed_len);
if (seed_len != seed_req_len) {
Safefree(pk_buf);
croak("sign_keypair: Invalid seed length: %lu", seed_len);
}
sk_pm = protmem_init(aTHX_ sk_len, g_protmem_default_flags_key);
if (sk_pm == NULL) {
Safefree(pk_buf);
croak("sign_keypair: Failed to allocate protmem");
}
if (seed_pm && protmem_grant(aTHX_ seed_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ sk_pm);
Safefree(pk_buf);
croak("sign_keypair: Failed to grant seed protmem RO");
inc/sign.xs view on Meta::CPAN
msg_pm = protmem_init(aTHX_ smsg_len - sig_len, smsg_pm->flags);
if (msg_pm == NULL)
croak("sign_open: Failed to allocate protmem");
if (protmem_grant(aTHX_ smsg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ msg_pm);
croak("sign_open: Failed to grant signed message protmem RO");
}
if (func(msg_pm->pm_ptr, NULL, smsg_buf, smsg_len, pk_buf) != 0) {
protmem_release(aTHX_ smsg_pm, PROTMEM_FLAG_MPROTECT_RO);
protmem_free(aTHX_ msg_pm);
croak("sign_open: Signature forged");
}
if (protmem_release(aTHX_ smsg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_free(aTHX_ msg_pm);
croak("sign_open: Failed to release signed message protmem RO");
}
if (protmem_release(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
protmem_free(aTHX_ msg_pm);
croak("sign_open: Failed to release msg protmem RO");
}
RETVAL = protmem_to_sv(aTHX_ msg_pm, MEMVAULT_CLASS);
}
else {
STRLEN msg_len = smsg_len - sig_len;
Newx(msg_buf, msg_len + 1, unsigned char);
if (msg_buf == NULL)
croak("sign_open: Failed to allocate memory");
msg_buf[msg_len] = '\0';
if (func(msg_buf, NULL, smsg_buf, smsg_len, pk_buf) != 0) {
Safefree(msg_buf);
croak("sign_open: Signature forged");
}
RETVAL = newSV(0);
sv_usepvn_flags(RETVAL, (char *)msg_buf, msg_len, SV_HAS_TRAILING_NUL);
}
OUTPUT:
RETVAL
void sign_to_curve25519(SV * pk, SV * sk, SV * flags = &PL_sv_undef)
ALIAS:
sign_ed25519_to_curve25519 = 1
PREINIT:
protmem *sk_pm = NULL, *sk_ed_pm;
SV *pk_ed_sv;
unsigned char *pk_buf, *sk_buf, *pk_ed_buf;
STRLEN pk_len, sk_len;
unsigned int sk_flags = g_protmem_default_flags_key;
PPCODE:
PERL_UNUSED_VAR(ix);
SvGETMAGIC(flags);
if (SvOK(flags))
sk_flags = SvUV_nomg(flags);
pk_buf = (unsigned char *)SvPVbyte(pk, pk_len);
if (pk_len != crypto_sign_ed25519_PUBLICKEYBYTES)
croak("sign_to_curve25519: Invalid public key length %lu", pk_len);
if (sv_derived_from(sk, MEMVAULT_CLASS)) {
sk_pm = protmem_get(aTHX_ sk, MEMVAULT_CLASS);
sk_buf = sk_pm->pm_ptr;
sk_len = sk_pm->size;
}
else
sk_buf = (unsigned char *)SvPVbyte(sk, sk_len);
if (sk_len != crypto_sign_ed25519_SECRETKEYBYTES)
croak("sign_to_curve25519: Invalid secret key length %lu", sk_len);
Newx(pk_ed_buf, crypto_scalarmult_curve25519_BYTES + 1, unsigned char);
if (pk_ed_buf == NULL)
croak("sign_to_curve25519: Failed to allocate memory");
pk_ed_buf[crypto_scalarmult_curve25519_BYTES] = '\0';
if (crypto_sign_ed25519_pk_to_curve25519(pk_ed_buf, pk_buf) != 0) {
Safefree(pk_ed_buf);
croak("sign_to_curve25519: Failed to convert public key to curve25519");
}
sk_ed_pm = protmem_init(aTHX_ crypto_scalarmult_curve25519_BYTES, sk_flags);
if (sk_ed_pm == NULL) {
Safefree(pk_ed_buf);
croak("sign_to_curve25519: Failed to allocate protmem");
}
if (sk_pm && protmem_grant(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
Safefree(pk_ed_buf);
protmem_free(aTHX_ sk_ed_pm);
croak("sign_to_curve25519: Failed to grant sk protmem RO");
}
if (crypto_sign_ed25519_sk_to_curve25519(sk_ed_pm->pm_ptr, sk_buf) != 0) {
Safefree(pk_ed_buf);
protmem_free(aTHX_ sk_ed_pm);
if (sk_pm)
protmem_release(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("sign_to_curve25519: Failed to convert secret key to curve25519");
}
if (sk_pm && protmem_release(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
Safefree(pk_ed_buf);
protmem_free(aTHX_ sk_ed_pm);
croak("sign_to_curve25519: Failed to release sk protmem RO");
}
if (protmem_release(aTHX_ sk_ed_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
Safefree(pk_ed_buf);
protmem_free(aTHX_ sk_ed_pm);
croak("sign_to_curve25519: Failed to release ed protmem RO");
}
pk_ed_sv = newSV(0);
sv_usepvn_flags(pk_ed_sv, (char *)pk_ed_buf, crypto_scalarmult_curve25519_BYTES,
SV_HAS_TRAILING_NUL);
mXPUSHs(pk_ed_sv);
mXPUSHs(protmem_to_sv(aTHX_ sk_ed_pm, MEMVAULT_CLASS));
XSRETURN(2);
void sign_verify(SV * msg, SV * sig, SV * pk)
ALIAS:
sign_ed25519_verify = 1
PREINIT:
protmem *msg_pm = NULL;
unsigned char *msg_buf, *sig_buf, *pk_buf;
STRLEN msg_len, sig_len, pk_len, sig_req_len, pk_req_len;
int ret;
int (*func)(const unsigned char *, const unsigned char *,
unsigned long long, const unsigned char *);
PPCODE:
switch(ix) {
case 1:
sig_req_len = crypto_sign_ed25519_BYTES;
pk_req_len = crypto_sign_ed25519_PUBLICKEYBYTES;
func = crypto_sign_ed25519_verify_detached;
break;
default:
sig_req_len = crypto_sign_BYTES;
pk_req_len = crypto_sign_PUBLICKEYBYTES;
func = crypto_sign_verify_detached;
}
sig_buf = (unsigned char *)SvPVbyte(sig, sig_len);
if (sig_len != sig_req_len)
croak("sign_verify: Invalid signature length %lu", sig_len);
pk_buf = (unsigned char *)SvPVbyte(pk, pk_len);
if (pk_len != pk_req_len)
croak("sign_verify: Invalid public key length %lu", pk_len);
if (sv_derived_from(msg, MEMVAULT_CLASS)) {
msg_pm = protmem_get(aTHX_ msg, MEMVAULT_CLASS);
msg_buf = msg_pm->pm_ptr;
msg_len = msg_pm->size;
}
else
msg_buf = (unsigned char *)SvPVbyte(msg, msg_len);
if (msg_pm && protmem_grant(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("sign_verify: Failed to grant msg protmem RO");
ret = func(sig_buf, msg_buf, msg_len, pk_buf);
if (msg_pm && protmem_release(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0)
croak("sign_verify: Failed to release msg protmem RO");
if (ret == 0)
XSRETURN_YES;
XSRETURN_NO;
MODULE = Crypt::Sodium::XS PACKAGE = Crypt::Sodium::XS::sign::multi
void DESTROY(SV * self)
ALIAS:
Crypt::Sodium::XS::sign::ed25519ph_multi::DESTROY = 1
PREINIT:
protmem *state_pm;
CODE:
switch(ix) {
case 1:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::ed25519ph_multi");
break;
default:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::multi");
}
protmem_free(aTHX_ state_pm);
inc/sign.xs view on Meta::CPAN
croak("final_sign: Failed to grant sk protmem RO");
}
switch(ix) {
case 1:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::ed25519ph_multi");
break;
default:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::multi");
}
if (protmem_grant(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
Safefree(sig_buf);
if (sk_pm)
protmem_release(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("final_sign: Failed to grant state protmem RW");
}
switch(ix) {
case 1:
crypto_sign_ed25519ph_final_create(state_pm->pm_ptr, sig_buf, NULL, sk_buf);
break;
default:
crypto_sign_final_create(state_pm->pm_ptr, sig_buf, NULL, sk_buf);
}
if (protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
Safefree(sig_buf);
if (sk_pm)
protmem_release(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO);
croak("final_sign: Failed to release state protmem RW");
}
if (sk_pm && protmem_release(aTHX_ sk_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
Safefree(sig_buf);
croak("final_sign: Failed to release sk protmem RO");
}
RETVAL = newSV(0);
switch(ix) {
case 1:
sv_usepvn_flags(RETVAL, (char *)sig_buf, crypto_sign_ed25519_BYTES, SV_HAS_TRAILING_NUL);
break;
default:
sv_usepvn_flags(RETVAL, (char *)sig_buf, crypto_sign_BYTES, SV_HAS_TRAILING_NUL);
}
OUTPUT:
RETVAL
void final_verify(SV * self, SV * sig, SV * pk)
ALIAS:
Crypt::Sodium::XS::sign::ed25519ph_multi::final_verify = 1
PREINIT:
protmem *state_pm;
unsigned char *sig_buf, *pk_buf;
STRLEN sig_len, pk_len;
int ret;
PPCODE:
sig_buf = (unsigned char *)SvPVbyte(sig, sig_len);
pk_buf = (unsigned char *)SvPVbyte(pk, pk_len);
switch(ix) {
case 1:
if (sig_len != crypto_sign_ed25519_BYTES)
croak("final_verify: Invalid signature length %lu", sig_len);
if (pk_len != crypto_sign_ed25519_PUBLICKEYBYTES)
croak("final_verify: Invalid public key length %lu", pk_len);
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::ed25519ph_multi");
break;
default:
if (sig_len != crypto_sign_BYTES)
croak("final_verify: Invalid signature length %lu", sig_len);
if (pk_len != crypto_sign_PUBLICKEYBYTES)
croak("final_verify: Invalid public key length %lu", pk_len);
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::multi");
}
if (protmem_grant(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("final_verify: Failed to grant state protmem RW");
switch(ix) {
case 1:
ret = crypto_sign_ed25519ph_final_verify(state_pm->pm_ptr, sig_buf, pk_buf);
break;
default:
ret = crypto_sign_final_verify(state_pm->pm_ptr, sig_buf, pk_buf);
}
if (protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("final_verify: Failed to release state protmem RW");
if (ret == 0)
XSRETURN_YES;
XSRETURN_NO;
void update(SV * self, ...)
ALIAS:
Crypt::Sodium::XS::sign::ed25519ph_multi::update = 1
PREINIT:
protmem *state_pm, *msg_pm;
unsigned char *msg_buf;
STRLEN msg_len;
I32 i;
PPCODE:
switch(ix) {
case 1:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::ed25519ph_multi");
break;
default:
state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::sign::multi");
}
if (protmem_grant(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("update: Failed to grant state protmem RW");
for (i = 1; i < items; i++) {
if (sv_derived_from(ST(i), MEMVAULT_CLASS)) {
msg_pm = protmem_get(aTHX_ ST(i), MEMVAULT_CLASS);
msg_buf = msg_pm->pm_ptr;
msg_len = msg_pm->size;
}
else
msg_buf = (unsigned char *)SvPVbyte(ST(i), msg_len);
if (msg_pm && protmem_grant(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW);
croak("update: Failed to grant msg protmem RO");
}
switch(ix) {
case 1:
crypto_sign_ed25519ph_update(state_pm->pm_ptr, msg_buf, msg_len);
break;
default:
crypto_sign_update(state_pm->pm_ptr, msg_buf, msg_len);
}
if (msg_pm && protmem_release(aTHX_ msg_pm, PROTMEM_FLAG_MPROTECT_RO) != 0) {
protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW);
croak("update: Failed to release msg protmem RO");
}
msg_pm = NULL;
}
if (protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0)
croak("update: Failed to release state protmem RW");
XSRETURN(1);
( run in 1.000 second using v1.01-cache-2.11-cpan-71847e10f99 )