diff options
author | Karel Miko <karel.miko@gmail.com> | 2018-01-29 10:54:33 +0100 |
---|---|---|
committer | Karel Miko <karel.miko@gmail.com> | 2018-01-29 10:54:33 +0100 |
commit | e8df4110fd7a64f832143fe378b8b87e9f6a1129 (patch) | |
tree | ebd431b8967e4acbe389ddb382470a8eda745bc5 /_generators | |
parent | cf16014b051cecefff3b5e1e7efa94d9130e26d3 (diff) |
moving more code to XS
Diffstat (limited to '_generators')
-rw-r--r-- | _generators/Mac.xs.inc.tt | 9 | ||||
-rw-r--r-- | _generators/Mode.pm.tt | 23 | ||||
-rw-r--r-- | _generators/Mode.xs.inc.tt | 57 | ||||
-rw-r--r-- | _generators/Mode_p.xs.inc.tt | 234 |
4 files changed, 166 insertions, 157 deletions
diff --git a/_generators/Mac.xs.inc.tt b/_generators/Mac.xs.inc.tt index 8a070345..85a5c74f 100644 --- a/_generators/Mac.xs.inc.tt +++ b/_generators/Mac.xs.inc.tt @@ -4,13 +4,13 @@ MODULE = CryptX PACKAGE = Crypt::Mac::[%orig_name%] Crypt::Mac::[%orig_name%] [%-IF lc_name == 'hmac' %] -new(char * class, char * hash_name, SV * key) +new(Class, char * hash_name, SV * key) [%-ELSIF lc_name == 'blake2s' || lc_name == 'blake2b' %] -new(char * class, unsigned long size, SV * key) +new(Class, unsigned long size, SV * key) [%-ELSIF lc_name == 'pelican' || lc_name == 'poly1305' %] -new(char * class, SV * key) +new(Class, SV * key) [%-ELSE%] -new(char * class, char * cipher_name, SV * key) +new(Class, char * cipher_name, SV * key) [%-END%] CODE: { @@ -31,7 +31,6 @@ new(char * class, char * cipher_name, SV * key) if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); [%-END%] - LTC_UNUSED_PARAM(class); if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); k = (unsigned char *) SvPVbyte(key, k_len); diff --git a/_generators/Mode.pm.tt b/_generators/Mode.pm.tt index 0c77ba12..19b1c421 100644 --- a/_generators/Mode.pm.tt +++ b/_generators/Mode.pm.tt @@ -7,7 +7,28 @@ use warnings; our $VERSION = '[%(pmver || "0.000")%]'; use Crypt::Cipher; -use base 'Crypt::Mode'; + +sub encrypt { + my ($self, $pt) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; +[%-IF lc_name == 'ecb' or lc_name == 'cbc' %] + $self->start_encrypt(@_)->add($pt) . $self->finish; +[%-ELSE%] + $self->start_encrypt(@_)->add($pt); +[%-END%] +} + +sub decrypt { + my ($self, $ct) = (shift, shift); + local $SIG{__DIE__} = \&CryptX::_croak; +[%-IF lc_name == 'ecb' or lc_name == 'cbc' %] + $self->start_decrypt(@_)->add($ct) . $self->finish; +[%-ELSE%] + $self->start_decrypt(@_)->add($ct); +[%-END%] +} + +sub CLONE_SKIP { 1 } # prevent cloning 1; diff --git a/_generators/Mode.xs.inc.tt b/_generators/Mode.xs.inc.tt index f4d98e01..4788c0db 100644 --- a/_generators/Mode.xs.inc.tt +++ b/_generators/Mode.xs.inc.tt @@ -4,13 +4,12 @@ MODULE = CryptX PACKAGE = Crypt::Mode::[%orig_name%] Crypt::Mode::[%orig_name%] [%-IF lc_name == 'ctr' %] -new(char * class, char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) +new(Class, char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) [%-ELSE%] -new(char * class, char * cipher_name, int rounds=0) +new(Class, char * cipher_name, int rounds=0) [%-END%] CODE: { - LTC_UNUSED_PARAM(class); Newz(0, RETVAL, 1, struct [%lc_name%]_struct); if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->direction = 0; @@ -85,42 +84,40 @@ start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv) } SV * -_crypt(Crypt::Mode::[%orig_name%] self, SV * data) +add(Crypt::Mode::[%orig_name%] self, ...) CODE: { - int rv; - STRLEN in_data_len; + int rv, j; + STRLEN in_data_len, out_len = 0; unsigned char *in_data, *out_data; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, in_data_len); - out_data = (unsigned char *)SvPVX(RETVAL); - - if (self->direction == 1) { - rv = [%lc_name%]_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); + if (in_data_len > 0) { + out_data = SvGROW(RETVAL, out_len + in_data_len + 1) + out_len; + out_len += in_data_len; + if (self->direction == 1) { + rv = [%lc_name%]_encrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); + } } - } - else if (self->direction == -1) { - rv = [%lc_name%]_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { + else if (self->direction == -1) { + rv = [%lc_name%]_decrypt(in_data, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); + } + } + else { SvREFCNT_dec(RETVAL); - croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); + croak("FATAL: [%lc_name%]_crypt failed: call start_encrypt or start_decrypt first"); } } - else { - SvREFCNT_dec(RETVAL); - croak("FATAL: [%lc_name%]_crypt failed: call start_encrypt or start_decrypt first"); - } } + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL diff --git a/_generators/Mode_p.xs.inc.tt b/_generators/Mode_p.xs.inc.tt index d5a47059..9b7429e1 100644 --- a/_generators/Mode_p.xs.inc.tt +++ b/_generators/Mode_p.xs.inc.tt @@ -3,10 +3,9 @@ MODULE = CryptX PACKAGE = Crypt::Mode::[%orig_name%] [%comment%] Crypt::Mode::[%orig_name%] -new(char * class, char * cipher_name, int padding=1, int rounds=0) +new(Class, char * cipher_name, int padding=1, int rounds=0) CODE: { - LTC_UNUSED_PARAM(class); Newz(0, RETVAL, 1, struct [%lc_name%]_struct); if (!RETVAL) croak("FATAL: Newz failed"); RETVAL->padding_mode = padding; @@ -70,157 +69,150 @@ start_decrypt(_XXX_XXX_XXX_) } SV * -_crypt(Crypt::Mode::[%orig_name%] self, SV * data) +add(Crypt::Mode::[%orig_name%] self, ...) CODE: { int rv, has_tmp_block, blen; - unsigned long i; - STRLEN in_data_len, in_data_start; + unsigned long i, j; + STRLEN in_data_len, in_data_start, out_len = 0; unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE]; - if (self->direction == 1) { - blen = (&self->state)->blocklen; - in_data_start = 0; - has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - if (self->padlen > 0) { - i = (blen - self->padlen); - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - in_data_len -= i; - in_data_start = i; - rv = [%lc_name%]_encrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; - } - } /* padlen > 0 */ - - i = (unsigned long)(in_data_len % blen); - if (in_data_len>0 && i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); - self->padlen = i; - in_data_len -= i; - } - - if (in_data_len > 0) { - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - RETVAL = NEWSV(0, i); /* avoid zero! */ - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); - if (has_tmp_block) { - Copy(tmp_block, out_data, blen, unsigned char); - out_data += blen; - } - rv = [%lc_name%]_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); - if (rv != CRYPT_OK) { - SvREFCNT_dec(RETVAL); - croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); - } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); - } - else { - RETVAL = newSVpvn("", 0); - } - } - } - else if (self->direction == -1) { + RETVAL = newSVpvn("", 0); + for (j = 1; j < items; j++) { + in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len); blen = (&self->state)->blocklen; in_data_start = 0; has_tmp_block = 0; - in_data = (unsigned char *)SvPVbyte(data, in_data_len); - if (in_data_len == 0) { - RETVAL = newSVpvn("", 0); - } - else { - - if (self->padlen == blen) { - rv = [%lc_name%]_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); - self->padlen = 0; - has_tmp_block = 1; - } /* padlen == blen */ - else if (self->padlen > 0) { - i = (blen - self->padlen); /* remaining bytes in padding buffer */ - if (in_data_len >= i) { /* enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, i, unsigned char); - self->padlen += i; - in_data_len -= i; - in_data_start = i; - if (in_data_len>0 || self->padding_mode == 0) { - rv = [%lc_name%]_decrypt(self->pad, tmp_block, blen, &self->state); - if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); + if (in_data_len > 0) { + if (self->direction == 1) { + /* handle non-empty self->pad buffer */ + if (self->padlen > 0) { + i = (blen - self->padlen); + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + in_data_len -= i; + in_data_start = i; + rv = [%lc_name%]_encrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); + } self->padlen = 0; has_tmp_block = 1; } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } } - else { /* not enough data to fill pad */ - Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); - self->padlen += (int)in_data_len; - in_data_len = 0; - } - } /* padlen > 0 */ - /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ - if (in_data_len>0) { i = (unsigned long)(in_data_len % blen); - if (i>0) { /* save tail of data into pad */ - Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + if (in_data_len > 0 && i > 0) { /* save tail of data into pad */ + Copy(in_data + in_data_start + in_data_len - i, self->pad, i, unsigned char); self->padlen = i; in_data_len -= i; } - } - if (in_data_len>0) { - if (self->padlen == 0 && self->padding_mode !=0) { - /* in case of padding keep full pad if no more data */ - Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); - self->padlen = blen; - in_data_len -= blen; - } - i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); - if (i == 0) { - RETVAL = newSVpvn("", 0); - } - else { - RETVAL = NEWSV(0, i); /* avoid zero! */ - SvPOK_only(RETVAL); - SvCUR_set(RETVAL, i); - out_data = (unsigned char *)SvPVX(RETVAL); + if (in_data_len > 0) { + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + out_data = SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; if (has_tmp_block) { Copy(tmp_block, out_data, blen, unsigned char); out_data += blen; } - rv = [%lc_name%]_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + rv = [%lc_name%]_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv)); + } + } /* in_data_len > 0 */ + else if (has_tmp_block) { + out_data = SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); + } + } + else if (self->direction == -1) { + if (self->padlen == blen) { + rv = [%lc_name%]_decrypt(self->pad, tmp_block, blen, &self->state); if (rv != CRYPT_OK) { SvREFCNT_dec(RETVAL); croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); } + self->padlen = 0; + has_tmp_block = 1; + } /* padlen == blen */ + else if (self->padlen > 0) { + i = (blen - self->padlen); /* remaining bytes in padding buffer */ + if (in_data_len >= i) { /* enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, i, unsigned char); + self->padlen += i; + in_data_len -= i; + in_data_start = i; + if (in_data_len>0 || self->padding_mode == 0) { + rv = [%lc_name%]_decrypt(self->pad, tmp_block, blen, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); + } + self->padlen = 0; + has_tmp_block = 1; + } + } + else { /* not enough data to fill pad */ + Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char); + self->padlen += (int)in_data_len; + in_data_len = 0; + } + } /* padlen > 0 */ + + /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */ + if (in_data_len>0) { + i = (unsigned long)(in_data_len % blen); + if (i>0) { /* save tail of data into pad */ + Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); + self->padlen = i; + in_data_len -= i; + } + } + + if (in_data_len>0) { + if (self->padlen == 0 && self->padding_mode !=0) { + /* in case of padding keep full pad if no more data */ + Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char); + self->padlen = blen; + in_data_len -= blen; + } + i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); + if (i > 0) { + out_data = SvGROW(RETVAL, out_len + i + 1) + out_len; + out_len += i; + if (has_tmp_block) { + Copy(tmp_block, out_data, blen, unsigned char); + out_data += blen; + } + rv = [%lc_name%]_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state); + if (rv != CRYPT_OK) { + SvREFCNT_dec(RETVAL); + croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv)); + } + } + } /* in_data_len>0 */ + else if (has_tmp_block) { + out_data = SvGROW(RETVAL, out_len + blen + 1) + out_len; + out_len += blen; + Copy(tmp_block, out_data, blen, unsigned char); } - } /* in_data_len>0 */ - else if (has_tmp_block) { - RETVAL = newSVpvn((char*)tmp_block, blen); } else { - RETVAL = newSVpvn("", 0); + SvREFCNT_dec(RETVAL); + croak("FATAL: call start_decryt or start_encrpyt first (%d)", self->direction); } } } - else { - croak("FATAL: call start_decryt or start_encrpyt first (%d)", self->direction); - } + if (out_len > 0) SvCUR_set(RETVAL, out_len); } OUTPUT: RETVAL |