File Coverage

inc/CryptX_Cipher.xs.inc
Criterion Covered Total %
statement 73 83 87.9
branch 54 88 61.3
condition n/a
subroutine n/a
pod n/a
total 127 171 74.2


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