Crypt-Sodium-XS

 view release on metacpan or  search on metacpan

inc/hkdf.xs  view on Meta::CPAN

MODULE = Crypt::Sodium::XS PACKAGE = Crypt::Sodium::XS::hkdf

void _define_constants()
  PREINIT:
  HV *stash = gv_stashpv("Crypt::Sodium::XS::hkdf", 0);

  PPCODE:
#ifdef SODIUM_HAS_HKDF
  newCONSTSUB(stash, "hkdf_sha256_BYTES_MAX",
              newSVuv(crypto_kdf_hkdf_sha256_BYTES_MAX));
  newCONSTSUB(stash, "hkdf_sha512_BYTES_MAX",
              newSVuv(crypto_kdf_hkdf_sha512_BYTES_MAX));
  newCONSTSUB(stash, "hkdf_sha256_BYTES_MIN",
              newSVuv(crypto_kdf_hkdf_sha256_BYTES_MIN));
  newCONSTSUB(stash, "hkdf_sha512_BYTES_MIN",
              newSVuv(crypto_kdf_hkdf_sha512_BYTES_MIN));
  newCONSTSUB(stash, "hkdf_sha256_KEYBYTES",
              newSVuv(crypto_kdf_hkdf_sha256_KEYBYTES));
  newCONSTSUB(stash, "hkdf_sha512_KEYBYTES",
              newSVuv(crypto_kdf_hkdf_sha512_KEYBYTES));
  newCONSTSUB(stash, "hkdf_available", &PL_sv_yes);
#else
  newCONSTSUB(stash, "hkdf_available", &PL_sv_no);
#endif

SV * hkdf_sha256_keygen(SV * flags = &PL_sv_undef)

  ALIAS:
  hkdf_sha256_keygen = 1
  hkdf_sha512_keygen = 2

  CODE:
  switch(ix) {
    case 1:
#ifdef SODIUM_HAS_HKDF
      RETVAL = sv_keygen(aTHX_ crypto_kdf_hkdf_sha256_KEYBYTES, flags);
#else
      croak("HKDF not supported by this version of libsodium");
#endif
      break;
    default:
#ifdef SODIUM_HAS_HKDF
      RETVAL = sv_keygen(aTHX_ crypto_kdf_hkdf_sha512_KEYBYTES, flags);
#else
      croak("HKDF not supported by this version of libsodium");
#endif
  }

  OUTPUT:
  RETVAL

SV * hkdf_sha256_extract( \
  SV * ikm, \
  SV * salt = &PL_sv_undef, \
  SV * flags = &PL_sv_undef \
)

  ALIAS:
  hkdf_sha512_extract = 1

  PREINIT:
  protmem *ikm_pm = NULL, *prk_pm;
  unsigned char *salt_buf = NULL, *ikm_buf;
  STRLEN prk_len, salt_len = 0, ikm_len;
  unsigned int prk_flags = g_protmem_default_flags_key;
  int (*func)(unsigned char *,
              const unsigned char *, size_t, const unsigned char *, size_t);

inc/hkdf.xs  view on Meta::CPAN

  CODE:

  SvGETMAGIC(flags);
  if (SvOK(flags))
    prk_flags = SvUV_nomg(flags);

  switch(ix) {
    case 1:
      prk_pm = protmem_init(aTHX_ crypto_kdf_hkdf_sha512_KEYBYTES, prk_flags);
      if (prk_pm == NULL)
        croak("final: Failed to allocate protmem");

      state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::hkdf::sha512_multi");
      break;
    default:
      prk_pm = protmem_init(aTHX_ crypto_kdf_hkdf_sha256_KEYBYTES, prk_flags);
      if (prk_pm == NULL)
        croak("final: Failed to allocate protmem");

      state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::hkdf::sha256_multi");
  }
  if (protmem_grant(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
    protmem_free(aTHX_ prk_pm);
    croak("final: Failed to grant state protmem RW");
  }

  switch(ix) {
    case 1:
      crypto_kdf_hkdf_sha512_extract_final(state_pm->pm_ptr, prk_pm->pm_ptr);
      break;
    default:
      crypto_kdf_hkdf_sha256_extract_final(state_pm->pm_ptr, prk_pm->pm_ptr);
  }

  if (protmem_release(aTHX_ state_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
    protmem_free(aTHX_ prk_pm);
    croak("final: Failed to release state protmem RW");
  }

  if (protmem_release(aTHX_ prk_pm, PROTMEM_FLAG_MPROTECT_RW) != 0) {
    protmem_free(aTHX_ prk_pm);
    croak("final: Failed to release prk protmem RW");
  }

  RETVAL = protmem_to_sv(aTHX_ prk_pm, MEMVAULT_CLASS);

  OUTPUT:
  RETVAL

SV * update(SV * self, ...)

  ALIAS:
  Crypt::Sodium::XS::hkdf::sha512_multi::update = 1

  PREINIT:
  protmem *state_pm, *msg_pm = NULL;
  unsigned char *msg_buf;
  STRLEN msg_len;
  I32 i;

  PPCODE:
  PERL_UNUSED_VAR(RETVAL);
  switch(ix) {
    case 1:
      state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::hkdf::sha512_multi");
      break;
    default:
      state_pm = protmem_get(aTHX_ self, "Crypt::Sodium::XS::hkdf::sha256_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_kdf_hkdf_sha512_extract_update(state_pm->pm_ptr, msg_buf, msg_len);
        break;
      default:
        crypto_kdf_hkdf_sha256_extract_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);

#endif



( run in 0.708 second using v1.01-cache-2.11-cpan-71847e10f99 )