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 3708           unsigned char *key_data = NULL;
12             SV *key;
13             SV *name_sv;
14             char *cipher_name;
15 3708           int rv, id, rounds = 0, idx;
16              
17             /* we need to handle:
18             Crypt::Cipher->new('AES');
19             Crypt::Cipher::AES->new();
20             */
21 3708           idx = strcmp("Crypt::Cipher", class) == 0 ? 1 : 0;
22 3708 50         if (idx + 1 > items) croak("FATAL: missing argument");
23 3708           name_sv = ST(idx);
24 3708 50         if (!SvPOK_spec(name_sv)) croak("FATAL: invalid cipher name");
    100          
    50          
    100          
    50          
25 3706           cipher_name = SvPVbyte(name_sv, name_len);
26 3706 50         if (idx + 2 > items) croak("FATAL: missing key argument");
27 3706           key = ST(idx + 1);
28 3706 100         if (idx + 3 <= items) rounds = (int)SvIV(ST(idx + 2));
29              
30 3706 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    50          
    50          
31 3706           key_data = (unsigned char *)SvPVbyte(key, key_len);
32              
33 3706           id = cryptx_internal_find_cipher(cipher_name);
34 3706 100         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
35              
36 3705           Newz(0, RETVAL, 1, struct cipher_struct);
37 3705 50         if (!RETVAL) croak("FATAL: Newz failed");
38              
39 3705           RETVAL->desc = &cipher_descriptor[id];
40 3705           rv = RETVAL->desc->setup(key_data, (int)key_len, rounds, &RETVAL->skey);
41 3705 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 3705           zeromem(&self->skey, sizeof(symmetric_key));
54 3705           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 122717 50         if (!SvPOK_spec(data)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
66 122717           plaintext = (unsigned char *)SvPVbyte(data, len);
67              
68 122717 100         if (len == 0) {
69 1           RETVAL = newSVpvn("", 0);
70             }
71 122716 50         else if (len == (STRLEN)self->desc->block_length) {
72 122716           RETVAL = NEWSV(0, len); /* avoid zero! */
73 122716           SvPOK_only(RETVAL);
74 122716           SvCUR_set(RETVAL, len);
75 122716           rv = self->desc->ecb_encrypt(plaintext, (unsigned char *)SvPVX(RETVAL), &self->skey);
76 122716 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 693 50         if (!SvPOK_spec(data)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
97 693           ciphertext = (unsigned char *)SvPVbyte(data, len);
98              
99 693 100         if (len == 0) {
100 1           RETVAL = newSVpvn("", 0);
101             }
102 692 50         else if (len == (STRLEN)self->desc->block_length) {
103 692           RETVAL = NEWSV(0, len); /* avoid zero! */
104 692           SvPOK_only(RETVAL);
105 692           SvCUR_set(RETVAL, len);
106 692           rv = self->desc->ecb_decrypt(ciphertext, (unsigned char *)SvPVX(RETVAL), &self->skey);
107 692 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 233 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
124 28           IV tmp = SvIV((SV*)SvRV(param));
125 28           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
126 28           RETVAL = obj->desc->block_length;
127             }
128             else {
129             STRLEN plen;
130 205 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
131 205           int rv, id = cryptx_internal_find_cipher(name);
132 205 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
133 205           rv = cipher_descriptor[id].block_length;
134 205 50         if (!rv) croak("FATAL: invalid block_length for '%s'", name);
135 205           RETVAL = rv;
136             }
137             }
138             OUTPUT:
139             RETVAL
140              
141             int
142             max_keysize(SV * param, char * extra = NULL)
143             CODE:
144             {
145 335 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
146 54           IV tmp = SvIV((SV*)SvRV(param));
147 54           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
148 54           RETVAL = obj->desc->max_key_length;
149             }
150             else {
151             STRLEN plen;
152 281 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
153 281           int rv, id = cryptx_internal_find_cipher(name);
154 281 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
155 281           rv = cipher_descriptor[id].max_key_length;
156 281 50         if (!rv) croak("FATAL: invalid max_key_length for '%s'", name);
157 281           RETVAL = rv;
158             }
159             }
160             OUTPUT:
161             RETVAL
162              
163             int
164             min_keysize(SV * param, char * extra = NULL)
165             CODE:
166             {
167 165 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
168 27           IV tmp = SvIV((SV*)SvRV(param));
169 27           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
170 27           RETVAL = obj->desc->min_key_length;
171             }
172             else {
173             STRLEN plen;
174 138 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
175 138           int rv, id = cryptx_internal_find_cipher(name);
176 138 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
177 138           rv = cipher_descriptor[id].min_key_length;
178 138 50         if (!rv) croak("FATAL: invalid min_key_length for '%s'", name);
179 138           RETVAL = rv;
180             }
181             }
182             OUTPUT:
183             RETVAL
184              
185             int
186             default_rounds(SV * param, char * extra = NULL)
187             CODE:
188             {
189 162 100         if (sv_isobject(param) && sv_derived_from(param, "Crypt::Cipher")) {
    50          
190 27           IV tmp = SvIV((SV*)SvRV(param));
191 27           Crypt__Cipher obj = INT2PTR(Crypt__Cipher, tmp);
192 27           RETVAL = obj->desc->default_rounds;
193             }
194             else {
195             STRLEN plen;
196 135 50         char *name = SvPOK_spec(param) && strcmp(SvPVbyte(param, plen), "Crypt::Cipher") ? SvPVbyte(param, plen) : extra;
    50          
    0          
    0          
    0          
    100          
197 135           int rv, id = cryptx_internal_find_cipher(name);
198 135 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", name);
199 135           rv = cipher_descriptor[id].default_rounds;
200 135 50         if (!rv) XSRETURN_UNDEF;
201 135           RETVAL = rv;
202             }
203             }
204             OUTPUT:
205             RETVAL