Crypt-Bear

 view release on metacpan or  search on metacpan

lib/Crypt/Bear.xs  view on Meta::CPAN

static const map hashs = {
	hash_entry_for(sha256),
	hash_entry_for(sha512),
	hash_entry_for(sha384),
	hash_entry_for(sha224),
	hash_entry_for(sha1),
	hash_entry_for(md5)
};
typedef const br_hash_class* hash_type;

typedef const struct hash_oid {
	size_t length;
	unsigned char oid[10];
} *hash_oid_type;
static const struct hash_oid sha1_oid   = { 20, { 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A } };
static const struct hash_oid sha224_oid = { 28, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 } };
static const struct hash_oid sha256_oid = { 32, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 } };
static const struct hash_oid sha384_oid = { 48, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 } };
static const struct hash_oid sha512_oid = { 64, { 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 } };

#define hash_oid_entry(name) make_map_pointer_entry(#name, &name ## _oid)
static const map hash_oids = {
	hash_oid_entry(sha1),
	hash_oid_entry(sha224),
	hash_oid_entry(sha256),
	hash_oid_entry(sha384),
	hash_oid_entry(sha512),
};

#define br_hash_update(hasher, data, length) (hasher->vtable->update)(&hasher->vtable, data, length)

#define br_hash_desc(hasher, field) (((hasher)->vtable->desc >> BR_HASHDESC_ ## field ## _OFF) & BR_HASHDESC_ ## field ##_MASK)
#define br_hash_output_size(hasher) br_hash_desc(hasher, OUT)
#define br_hash_state_size(hasher) br_hash_desc(hasher, STATE)
#define br_hash_digest(hasher) ((self)->vtable)
static br_ghash ghash_impl;
#define br_hmac_key_digest br_hmac_key_get_digest
#define br_hmac_digest br_hmac_get_digest

typedef br_hash_compat_context* Crypt__Bear__Hash;
typedef br_hmac_key_context* Crypt__Bear__HMAC__Key;
typedef br_hmac_context* Crypt__Bear__HMAC;


/* KDF stuff */

typedef br_hkdf_context* Crypt__Bear__HKDF;
// typedef br_shake_context* Crypt__Bear__Shake;

/* Block stuff */

static const br_block_cbcenc_class* aes_cbc_enc;
static const br_block_cbcdec_class* aes_cbc_dec;
static const br_block_ctr_class* aes_ctr;
static const br_block_ctrcbc_class* aes_ctrcbc;

#define br_block_cbcenc_block_size(cbcenc) (*cbcenc)->block_size
#define br_block_cbcdec_block_size(cbcdec) (*cbcdec)->block_size
#define br_block_ctr_block_size(ctr) (*ctr)->block_size

typedef const br_block_cbcenc_class** Crypt__Bear__CBC__Enc;
typedef const br_block_cbcdec_class** Crypt__Bear__CBC__Dec;
typedef const br_block_ctr_class** Crypt__Bear__CTR;
typedef const br_block_ctrcbc_class** Crypt__Bear__CTRCBC;

typedef br_aes_gen_cbcenc_keys* Crypt__Bear__AES_CBC__Enc;
typedef br_aes_gen_cbcdec_keys* Crypt__Bear__AES_CBC__Dec;
typedef br_aes_gen_ctr_keys* Crypt__Bear__AES_CTR;
typedef br_aes_gen_ctrcbc_keys* Crypt__Bear__AES_CTRCBC;


/* AEAD stuff */

#define br_aead_reset(self, iv, ivlen) ((*(self))->reset)(self, iv, ivlen)
#define br_aead_aad_inject(self, ad, adlen) ((*(self))->aad_inject)(self, ad, adlen)
#define br_aead_flip(self) ((*(self))->flip)(self)
#define br_aead_run(self, encrypt, out, outlen) ((*(self))->run)(self, encrypt, out, outlen)
#define br_aead_get_tag(self, buffer) ((*(self))->get_tag)(self, buffer)
#define br_aead_check_tag(self, buffer) ((*(self))->check_tag)(self, buffer)

typedef const br_aead_class** Crypt__Bear__AEAD;
typedef br_gcm_context* Crypt__Bear__GCM;
typedef br_eax_context* Crypt__Bear__EAX;
typedef br_ccm_context* Crypt__Bear__CCM;


/* PRNG stuff */

static br_prng_seeder system_seeder;
static const char* system_seeder_name;
#define br_prng_system_seeder_name(class) system_seeder_name
#define br_prng_update(prng, data, length) ((*prng)->update)(prng, data, length)
#define br_hmac_drbg_digest br_hmac_drbg_get_hash

typedef const br_prng_class** Crypt__Bear__PRNG;
typedef br_hmac_drbg_context* Crypt__Bear__HMAC__DRBG;
typedef br_aesctr_drbg_context* Crypt__Bear__AES_CTR__DRBG;


/* RSA stuff */

static br_rsa_pkcs1_vrfy rsa_pkcs1_verify;
static br_rsa_pkcs1_sign rsa_pkcs1_sign;
static br_rsa_oaep_encrypt rsa_oaep_encrypt;
static br_rsa_oaep_decrypt rsa_oaep_decrypt;
static br_rsa_keygen br_rsa_generate_keypair;

static void S_rsa_key_copy(pTHX_ br_rsa_public_key* dest, const br_rsa_public_key* source) {
	char* buffer = safemalloc(source->nlen + source->elen);
	dest->n = memcpy(buffer, source->n, source->nlen);
	dest->nlen = source->nlen;
	buffer += source->nlen;
	dest->e = memcpy(buffer, source->e, source->elen);
	dest->elen = source->elen;
}
#define rsa_key_copy(dest, source) S_rsa_key_copy(aTHX_ dest, source)

#define rsa_key_destroy(target) Safefree((target)->n)

static int rsa_key_dup(pTHX_ MAGIC* magic, CLONE_PARAMS* params) {
	br_rsa_public_key* old = (br_rsa_public_key*)magic->mg_ptr;
	br_rsa_public_key* self = safemalloc(sizeof(br_rsa_public_key));
	rsa_key_copy(self, old);
	magic->mg_ptr = (char*)self;
	return 0;
}

static int rsa_key_free(pTHX_ SV* sv, MAGIC* magic) {
	br_rsa_public_key* self = (br_rsa_public_key*)magic->mg_ptr;

lib/Crypt/Bear.xs  view on Meta::CPAN

OUTPUT:
	RETVAL

IV br_hmac_size(Crypt::Bear::HMAC self)

void br_hmac_update(Crypt::Bear::HMAC self, const char* data, size_t length(data))

SV* br_hmac_out(Crypt::Bear::HMAC self)
CODE:
	RETVAL = make_buffer(br_hmac_size(self));
	br_hmac_out(self, SvPVX(RETVAL));
OUTPUT:
	RETVAL

hash_type br_hmac_digest(Crypt::Bear::HMAC self)


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HKDF PREFIX = br_hkdf_

Crypt::Bear::HKDF br_hkdf_new(class, hash_type hash, const char* salt, size_t length(salt))
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_hkdf_init(RETVAL, hash, salt, STRLEN_length_of_salt);
OUTPUT:
	RETVAL

void br_hkdf_inject(Crypt::Bear::HKDF self, const char* data, size_t length(data))

void br_hkdf_flip(Crypt::Bear::HKDF self)

SV* br_hkdf_produce(Crypt::Bear::HKDF self, size_t output_size, const char* info, size_t length(info))
CODE:
	RETVAL = make_buffer(output_size);
	br_hkdf_produce(self, info, STRLEN_length_of_info, SvPV_nolen(RETVAL), output_size);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::Shake PREFIX = br_shake_

#if 0
Crypt::Bear::Shake br_shake_new(class, hash_type hash, UV security_level)
CODE:
OUTPUT:
	RETVAL

void br_shake_inject(Crypt::Bear::Shake self, const char* data, size_t length(data))

void br_shake_flip(Crypt::Bear::Shake self)

SV* br_shake_produce(Crypt::Bear::Shake self, const char* info, size_t length(info))
CODE:
	RETVAL = make_buffer(output_size);
	br_shake_produce(self, info, STRLEN_length_of_info, SvPV_nolen(RETVAL), output_size);
OUTPUT:
	RETVAL

#endif


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CBC::Enc PREFIX = br_block_cbcenc_

IV br_block_cbcenc_block_size(Crypt::Bear::CBC::Enc self)

SV* br_block_cbcenc_run(Crypt::Bear::CBC::Enc self, const char* iv, STRLEN length(iv), const char* data, size_t length(data))
CODE:
	if ((STRLEN_length_of_data % br_block_cbcenc_block_size(self)) != 0)
		Perl_croak(aTHX_ "Data size should be a multiple of %u bytes", br_block_cbcenc_block_size(self));
	if (STRLEN_length_of_iv != br_block_cbcenc_block_size(self))
		Perl_croak(aTHX_ "IV should be %u bytes", br_block_cbcenc_block_size(self));

	char iv_copy[STRLEN_length_of_iv];
	memcpy(iv_copy, iv, STRLEN_length_of_iv);
	RETVAL = newSVpvn(data, STRLEN_length_of_data);
	((*self)->run)(self, iv_copy, SvPV_nolen(RETVAL), STRLEN_length_of_data);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CBC::Dec PREFIX = br_block_cbcdec_

IV br_block_cbcdec_block_size(Crypt::Bear::CBC::Dec self)

SV* br_block_cbcdec_run(Crypt::Bear::CBC::Dec self, const char* iv, STRLEN length(iv), const char* data, size_t length(data))
CODE:
	if ((STRLEN_length_of_data % br_block_cbcdec_block_size(self)) != 0)
		Perl_croak(aTHX_ "data size should be a multiple of %u bytes", br_block_cbcdec_block_size(self));
	if (STRLEN_length_of_iv != br_block_cbcdec_block_size(self))
		Perl_croak(aTHX_ "IV should be %u bytes", br_block_cbcdec_block_size(self));

	char iv_copy[STRLEN_length_of_iv];
	memcpy(iv_copy, iv, STRLEN_length_of_iv);
	RETVAL = newSVpvn(data, STRLEN_length_of_data);
	((*self)->run)(self, iv_copy, SvPV_nolen(RETVAL), STRLEN_length_of_data);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CTR PREFIX = br_block_ctr_

IV br_block_ctr_block_size(Crypt::Bear::CTR self)

SV* br_block_ctr_run(Crypt::Bear::CTR self, const char* iv, STRLEN length(iv), U32 counter, const char* data, size_t length(data))
CODE:
	if ((STRLEN_length_of_data % br_block_ctr_block_size(self)) != 0)
		Perl_croak(aTHX_ "data size should be a multiple of %u bytes", br_block_ctr_block_size(self));
	if (STRLEN_length_of_iv != br_block_ctr_block_size(self))
		Perl_croak(aTHX_ "IV should be %u bytes", br_block_ctr_block_size(self));

	char iv_copy[STRLEN_length_of_iv];
	memcpy(iv_copy, iv, STRLEN_length_of_iv);
	RETVAL = newSVpvn(data, STRLEN_length_of_data);
	((*self)->run)(self, iv_copy, counter, SvPV_nolen(RETVAL), STRLEN_length_of_data);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CBC::Enc PREFIX = br_block_aes_cbcenc_
BOOT:
	push_isa(Crypt::Bear::AES_CBC::Enc, Crypt::Bear::CBC::Enc);
	aes_cbc_enc = br_aes_x86ni_cbcenc_get_vtable();
	if (!aes_cbc_enc)
		aes_cbc_enc = &br_aes_ct_cbcenc_vtable;

Crypt::Bear::AES_CBC::Enc br_block_aes_cbcenc_new(class, const char* key, size_t length(key))
CODE:
	RETVAL = safemalloc(aes_cbc_enc->context_size);
	(aes_cbc_enc->init)((const br_block_cbcenc_class**)RETVAL, key, STRLEN_length_of_key);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CBC::Dec PREFIX = br_block_aes_cbcdec_
BOOT:
	push_isa(Crypt::Bear::AES_CBC::Dec, Crypt::Bear::CBC::Dec);
	aes_cbc_dec = br_aes_x86ni_cbcdec_get_vtable();
	if (!aes_cbc_dec)
#if IVSIZE == 8
		aes_cbc_dec = &br_aes_ct64_cbcdec_vtable;
#else
		aes_cbc_dec = &br_aes_ct_cbcdec_vtable;
#endif

Crypt::Bear::AES_CBC::Dec br_block_aes_cbcdec_new(class, const char* key, size_t length(key))
CODE:
	RETVAL = safemalloc(aes_cbc_dec->context_size);
	(aes_cbc_dec->init)((const br_block_cbcdec_class**)RETVAL, key, STRLEN_length_of_key);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTR PREFIX = br_block_aes_ctr_
BOOT:
	push_isa(Crypt::Bear::AES_CTR, Crypt::Bear::CTR);
	aes_ctr = br_aes_x86ni_ctr_get_vtable();
	if (!aes_ctr)
#if IVSIZE == 8
		aes_ctr = &br_aes_ct64_ctr_vtable;
#else
		aes_ctr = &br_aes_ct_ctr_vtable;
#endif

Crypt::Bear::AES_CTR br_block_aes_ctr_new(class, const char* key, size_t length(key))
CODE:
	RETVAL = safemalloc(aes_ctr->context_size);
	(aes_ctr->init)(&RETVAL->vtable, key, STRLEN_length_of_key);
OUTPUT:
	RETVAL

MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CTRCBC PREFIX = br_block_ctrcbc_


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTRCBC PREFIX = br_block_aes_ctrcbc_
BOOT:
	push_isa(Crypt::Bear::AES_CTRCBC, Crypt::Bear::CTRCBC);
	aes_ctrcbc = br_aes_x86ni_ctrcbc_get_vtable();
	if (!aes_ctrcbc)
		aes_ctrcbc = &br_aes_ct_ctrcbc_vtable;

Crypt::Bear::AES_CTRCBC br_block_aes_ctrcbc_new(class, const char* data, size_t length(data))
CODE:
	RETVAL = safemalloc(aes_ctrcbc->context_size);
	(aes_ctrcbc->init)(&RETVAL->vtable, data, STRLEN_length_of_data);
OUTPUT:
	RETVAL

MODULE = Crypt::Bear PACKAGE = Crypt::Bear::ChaCha20



MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AEAD PREFIX = br_aead_

void br_aead_reset(Crypt::Bear::AEAD self, const char* iv, size_t length(iv))

void br_aead_aad_inject(Crypt::Bear::AEAD self, const char* iv, size_t length(iv))

void br_aead_flip(Crypt::Bear::AEAD self)

SV* run(Crypt::Bear::AEAD self, const char* data, size_t length(data), bool encrypt)
CODE:
	RETVAL = newSVpvn(data, STRLEN_length_of_data);
	br_aead_run(self, encrypt, SvPV_nolen(RETVAL), STRLEN_length_of_data);
OUTPUT:
	RETVAL

SV* get_tag(Crypt::Bear::AEAD self)
CODE:
	RETVAL = make_buffer((*self)->tag_size);
	br_aead_get_tag(self, SvPVX(RETVAL));
OUTPUT:
	RETVAL

bool check_tag(Crypt::Bear::AEAD self, const char* tag, size_t length(tag))
CODE:
	if (STRLEN_length_of_tag != (*self)->tag_size)
		Perl_croak(aTHX_ "Incorrect tag size, got %zu expected %zu", STRLEN_length_of_tag, (*self)->tag_size);
	RETVAL = br_aead_check_tag(self, tag);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::GCM PREFIX = br_gcm_
BOOT:
	push_isa(Crypt::Bear::GCM, Crypt::Bear::AEAD);
	ghash_impl = br_ghash_pclmul_get();
	if (!ghash_impl)
#if IVSIZE == 8
		ghash_impl = &br_ghash_ctmul64;
#else
		ghash_impl = &br_ghash_ctmul;
#endif


Crypt::Bear::GCM br_gcm_new(class, Crypt::Bear::CTR ctr)
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_gcm_init(RETVAL, ctr, ghash_impl);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::EAX PREFIX = br_eax_
BOOT:
	push_isa(Crypt::Bear::EAX, Crypt::Bear::AEAD);

Crypt::Bear::EAX br_eax_new(class, Crypt::Bear::CTRCBC ctrcbc)
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_eax_init(RETVAL, ctrcbc);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::CCM PREFIX = br_ccm_
BOOT:
	push_isa(Crypt::Bear::CCM, Crypt::Bear::AEAD);

Crypt::Bear::CCM br_ccm_new(class, Crypt::Bear::CTRCBC ctrcbc)
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_ccm_init(RETVAL, ctrcbc);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::PRNG PREFIX = br_prng_
BOOT:
	system_seeder = br_prng_seeder_system(&system_seeder_name);

const char* br_prng_system_seeder_name(class)

SV* br_prng_generate(Crypt::Bear::PRNG self, size_t length)
CODE:
	RETVAL = make_buffer(length);
	((*self)->generate)(self, SvPVX(RETVAL), length);
OUTPUT:
	RETVAL

void br_prng_update(Crypt::Bear::PRNG self, const char* data, size_t length(data))

bool br_prng_system_seed(Crypt::Bear::PRNG self)
CODE:
	RETVAL = system_seeder ? system_seeder(self) : FALSE;
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::HMAC::DRBG PREFIX = br_hmac_drbg_
BOOT:
	push_isa(Crypt::Bear::HMAC::DRBG, Crypt::Bear::PRNG);

Crypt::Bear::HMAC::DRBG br_hmac_drbg_new(class, hash_type hash, const char* seed, size_t length(seed))
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_hmac_drbg_init(RETVAL, hash, seed, STRLEN_length_of_seed);
OUTPUT:
	RETVAL

hash_type br_hmac_drbg_digest(Crypt::Bear::HMAC::DRBG self)


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::AES_CTR::DRBG PREFIX = br_aesctr_drbg_
BOOT:
	push_isa(Crypt::Bear::AES_CTR::DRBG, Crypt::Bear::PRNG);


Crypt::Bear::AES_CTR::DRBG br_aesctr_drbg_new(class, const char* seed, size_t length(seed))
CODE:
	RETVAL = safemalloc(sizeof *RETVAL);
	br_aesctr_drbg_init(RETVAL, aes_ctr, seed, STRLEN_length_of_seed);
OUTPUT:
	RETVAL


MODULE = Crypt::Bear PACKAGE = Crypt::Bear::RSA PREFIX = br_rsa_
BOOT:
	br_rsa_generate_keypair = br_rsa_keygen_get_default();



( run in 1.145 second using v1.01-cache-2.11-cpan-e1769b4cff6 )