File Coverage

inc/CryptX_Cipher.xs.inc
Criterion Covered Total %
statement 81 89 91.0
branch 69 144 47.9
condition n/a
subroutine n/a
pod n/a
total 150 233 64.3


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::Cipher
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::Cipher
6             new(char * class, ...)
7             CODE:
8             {
9             STRLEN name_len;
10             STRLEN key_len;
11 3689           unsigned char *key_data = NULL;
12             SV *key;
13             SV *name_sv;
14             char *cipher_name;
15 3689           int rv, id, rounds = 0, idx;
16              
17             /* we need to handle:
18             Crypt::Cipher->new('AES');
19             Crypt::Cipher::AES->new();
20             */
21 3689           idx = strcmp("Crypt::Cipher", class) == 0 ? 1 : 0;
22 3689 50         if (idx + 1 > items) croak("FATAL: missing argument");
23 3689           name_sv = ST(idx);
24 3689 50         if (!SvPOK_spec(name_sv)) croak("FATAL: invalid cipher name");
    100          
    50          
    100          
    50          
25 3687           cipher_name = SvPVbyte(name_sv, name_len);
26 3687 50         if (idx + 2 > items) croak("FATAL: missing key argument");
27 3687           key = ST(idx + 1);
28 3687 100         if (idx + 3 <= items) rounds = (int)SvIV(ST(idx + 2));
29              
30 3687 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    50          
    50          
31 3687           key_data = (unsigned char *)SvPVbyte(key, key_len);
32              
33 3687           id = cryptx_internal_find_cipher(cipher_name);
34 3687 100         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
35              
36 3686           Newz(0, RETVAL, 1, struct cipher_struct);
37 3686 50         if (!RETVAL) croak("FATAL: Newz failed");
38              
39 3686           RETVAL->desc = &cipher_descriptor[id];
40 3686           rv = RETVAL->desc->setup(key_data, (int)key_len, rounds, &RETVAL->skey);
41 3686 50         if (rv != CRYPT_OK) {
42 0           Safefree(RETVAL);
43 0           croak("FATAL: cipher setup failed: %s", error_to_string(rv));
44             }
45             }
46             OUTPUT:
47             RETVAL
48              
49             void
50             DESTROY(Crypt::Cipher self)
51             CODE:
52             {
53 3686           zeromem(&self->skey, sizeof(symmetric_key));
54 3686           Safefree(self);
55             }
56              
57             SV *
58             encrypt(Crypt::Cipher self, SV * data)
59             CODE:
60             {
61             int rv;
62             STRLEN len;
63             unsigned char *plaintext;
64              
65 122713 50         if (!SvPOK_spec(data)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
66 122713           plaintext = (unsigned char *)SvPVbyte(data, len);
67              
68 122713 100         if (len == 0) {
69 1           RETVAL = newSVpvn("", 0);
70             }
71 122712 50         else if (len == (STRLEN)self->desc->block_length) {
72 122712           RETVAL = NEWSV(0, len); /* avoid zero! */
73 122712           SvPOK_only(RETVAL);
74 122712           SvCUR_set(RETVAL, len);
75 122712           rv = self->desc->ecb_encrypt(plaintext, (unsigned char *)SvPVX(RETVAL), &self->skey);
76 122712 50         if (rv!=CRYPT_OK) {
77 0           SvREFCNT_dec(RETVAL);
78 0           croak("FATAL: encrypt failed: %s", error_to_string(rv));
79             }
80             }
81             else {
82 0           croak ("FATAL: input size not equal to blocksize (%d)", self->desc->block_length);
83             }
84             }
85             OUTPUT:
86             RETVAL
87              
88             SV *
89             decrypt(Crypt::Cipher self, SV * data)
90             CODE:
91             {
92             int rv;
93             STRLEN len;
94             unsigned char *ciphertext;
95              
96 689 50         if (!SvPOK_spec(data)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
97 689           ciphertext = (unsigned char *)SvPVbyte(data, len);
98              
99 689 100         if (len == 0) {
100 1           RETVAL = newSVpvn("", 0);
101             }
102 688 50         else if (len == (STRLEN)self->desc->block_length) {
103 688           RETVAL = NEWSV(0, len); /* avoid zero! */
104 688           SvPOK_only(RETVAL);
105 688           SvCUR_set(RETVAL, len);
106 688           rv = self->desc->ecb_decrypt(ciphertext, (unsigned char *)SvPVX(RETVAL), &self->skey);
107 688 50         if (rv!=CRYPT_OK) {
108 0           SvREFCNT_dec(RETVAL);
109 0           croak("FATAL: decrypt failed: %s", error_to_string(rv));
110             }
111             }
112             else {
113 0           croak ("FATAL: input size not equal to blocksize (%d)", self->desc->block_length);
114             }
115             }
116             OUTPUT:
117             RETVAL
118              
119             int
120             blocksize(SV * param, char * extra = NULL)
121             CODE:
122             {
123 227 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
124 27           IV tmp = SvIV((SV*)SvRV(param));
125 27           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
126 27           RETVAL = obj->desc->block_length;
127             }
128             else {
129             STRLEN plen;
130 200 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
131 200           int rv, id = cryptx_internal_find_cipher(name);
132 200 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
133 200           rv = cipher_descriptor[id].block_length;
134 200 50         if (!rv) croak("FATAL: invalid block_length for '%s'", name);
135 200           RETVAL = rv;
136             }
137             }
138             OUTPUT:
139             RETVAL
140              
141             int
142             max_keysize(SV * param, char * extra = NULL)
143             CODE:
144             {
145 323 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
146 52           IV tmp = SvIV((SV*)SvRV(param));
147 52           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
148 52           RETVAL = obj->desc->max_key_length;
149             }
150             else {
151             STRLEN plen;
152 271 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
153 271           int rv, id = cryptx_internal_find_cipher(name);
154 271 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
155 271           rv = cipher_descriptor[id].max_key_length;
156 271 50         if (!rv) croak("FATAL: invalid max_key_length for '%s'", name);
157 271           RETVAL = rv;
158             }
159             }
160             OUTPUT:
161             RETVAL
162              
163             int
164             min_keysize(SV * param, char * extra = NULL)
165             CODE:
166             {
167 159 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
168 26           IV tmp = SvIV((SV*)SvRV(param));
169 26           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
170 26           RETVAL = obj->desc->min_key_length;
171             }
172             else {
173             STRLEN plen;
174 133 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
175 133           int rv, id = cryptx_internal_find_cipher(name);
176 133 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
177 133           rv = cipher_descriptor[id].min_key_length;
178 133 50         if (!rv) croak("FATAL: invalid min_key_length for '%s'", name);
179 133           RETVAL = rv;
180             }
181             }
182             OUTPUT:
183             RETVAL
184              
185             int
186             default_rounds(SV * param, char * extra = NULL)
187             CODE:
188             {
189 156 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
190 26           IV tmp = SvIV((SV*)SvRV(param));
191 26           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
192 26           RETVAL = obj->desc->default_rounds;
193             }
194             else {
195             STRLEN plen;
196 130 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
197 130           int rv, id = cryptx_internal_find_cipher(name);
198 130 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
199 130           rv = cipher_descriptor[id].default_rounds;
200 130 50         if (!rv) XSRETURN_UNDEF;
201 130           RETVAL = rv;
202             }
203             }
204             OUTPUT:
205             RETVAL