File Coverage

inc/CryptX_Mode_CBC.xs.inc
Criterion Covered Total %
statement 135 160 84.3
branch 100 148 67.5
condition n/a
subroutine n/a
pod n/a
total 235 308 76.3


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::Mode::CBC
2              
3             PROTOTYPES: DISABLE
4              
5             ### BEWARE - GENERATED FILE, DO NOT EDIT MANUALLY!
6              
7             Crypt::Mode::CBC
8             new(Class, char * cipher_name, int padding=1, int rounds=0)
9             CODE:
10             {
11 144           Newz(0, RETVAL, 1, struct cbc_struct);
12 144 50         if (!RETVAL) croak("FATAL: Newz failed");
13 144           RETVAL->padding_mode = padding;
14 144           RETVAL->padlen = 0;
15 144           RETVAL->direction = 0;
16 144           RETVAL->cipher_rounds = rounds;
17 144           RETVAL->cipher_id = cryptx_internal_find_cipher(cipher_name);
18 144 50         if (RETVAL->cipher_id == -1) {
19 0           Safefree(RETVAL);
20 0           croak("FATAL: find_cipfer failed for '%s'", cipher_name);
21             }
22             }
23             OUTPUT:
24             RETVAL
25              
26             void
27             DESTROY(Crypt::Mode::CBC self)
28             CODE:
29 144           Safefree(self);
30              
31             void
32             start_decrypt(Crypt::Mode::CBC self, SV * key, SV * iv)
33             ALIAS:
34             start_encrypt = 1
35             PPCODE:
36             {
37             int rv;
38 339           STRLEN k_len=0;
39 339           unsigned char *k=NULL;
40 339           STRLEN i_len=0;
41 339           unsigned char *i=NULL;
42              
43 339 50         if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
44 339 50         k = (unsigned char *) SvPVbyte(key, k_len);
45              
46 339 50         if (!SvPOK(iv)) croak("FATAL: iv must be string/buffer scalar");
47 339 50         i = (unsigned char *) SvPVbyte(iv, i_len);
48 339 50         if (i_len != (STRLEN)cipher_descriptor[self->cipher_id].block_length) {
49 0           croak ("FATAL: sizeof(iv) should be equal to blocksize (%d)", cipher_descriptor[self->cipher_id].block_length);
50             }
51 339           rv = cbc_start(self->cipher_id, i, k, (unsigned long)k_len, self->cipher_rounds, &self->state);
52 339 50         if (rv != CRYPT_OK) {
53 0           croak("FATAL: cbc_start failed: %s", error_to_string(rv));
54             }
55              
56 339 100         self->direction = ix == 1 ? 1 : -1;
57 339           self->padlen = 0;
58 339 50         XPUSHs(ST(0)); /* return self */
59             }
60              
61             SV *
62             add(Crypt::Mode::CBC self, ...)
63             CODE:
64             {
65             int rv, has_tmp_block, blen, j;
66             unsigned long i;
67 3505           STRLEN in_data_len, in_data_start, out_len = 0;
68             unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
69              
70 3505           RETVAL = newSVpvn("", 0);
71 7010 100         for (j = 1; j < items; j++) {
72 3505 100         in_data = (unsigned char *)SvPVbyte(ST(j), in_data_len);
73 3505           blen = (&self->state)->blocklen;
74 3505           in_data_start = 0;
75 3505           has_tmp_block = 0;
76 3505 50         if (in_data_len > 0) {
77 3505 100         if (self->direction == 1) {
78             /* handle non-empty self->pad buffer */
79 1681 100         if (self->padlen > 0) {
80 1360           i = (blen - self->padlen);
81 1360 100         if (in_data_len >= i) { /* enough data to fill pad */
82 585           Copy(in_data, self->pad+self->padlen, i, unsigned char);
83 585           in_data_len -= i;
84 585           in_data_start = i;
85 585           rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state);
86 585 50         if (rv != CRYPT_OK) {
87 0           SvREFCNT_dec(RETVAL);
88 0           croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv));
89             }
90 585           self->padlen = 0;
91 585           has_tmp_block = 1;
92             }
93             else { /* not enough data to fill pad */
94 775           Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char);
95 775           self->padlen += (int)in_data_len;
96 775           in_data_len = 0;
97             }
98             }
99              
100 1681           i = (unsigned long)(in_data_len % blen);
101 1681 100         if (in_data_len > 0 && i > 0) { /* save tail of data into pad */
    100          
102 671           Copy(in_data + in_data_start + in_data_len - i, self->pad, i, unsigned char);
103 671           self->padlen = i;
104 671           in_data_len -= i;
105             }
106              
107 1681 100         if (in_data_len > 0) {
108 246 100         i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len);
109 246 50         out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len;
    50          
110 246           out_len += i;
111 246 100         if (has_tmp_block) {
112 96           Copy(tmp_block, out_data, blen, unsigned char);
113 96           out_data += blen;
114             }
115 246           rv = cbc_encrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state);
116 246 50         if (rv != CRYPT_OK) {
117 0           SvREFCNT_dec(RETVAL);
118 0           croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv));
119             }
120             } /* in_data_len > 0 */
121 1435 100         else if (has_tmp_block) {
122 489 50         out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len;
    50          
123 489           out_len += blen;
124 1681           Copy(tmp_block, out_data, blen, unsigned char);
125             }
126             }
127 1824 50         else if (self->direction == -1) {
128 1824 100         if (self->padlen == blen) {
129 116           rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state);
130 116 50         if (rv != CRYPT_OK) {
131 0           SvREFCNT_dec(RETVAL);
132 0           croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv));
133             }
134 116           self->padlen = 0;
135 116           has_tmp_block = 1;
136             } /* padlen == blen */
137 1708 100         else if (self->padlen > 0) {
138 1470           i = (blen - self->padlen); /* remaining bytes in padding buffer */
139 1470 100         if (in_data_len >= i) { /* enough data to fill pad */
140 633           Copy(in_data, self->pad+self->padlen, i, unsigned char);
141 633           self->padlen += i;
142 633           in_data_len -= i;
143 633           in_data_start = i;
144 633 100         if (in_data_len>0 || self->padding_mode == 0) {
    100          
145 501           rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state);
146 501 50         if (rv != CRYPT_OK) {
147 0           SvREFCNT_dec(RETVAL);
148 0           croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv));
149             }
150 501           self->padlen = 0;
151 633           has_tmp_block = 1;
152             }
153             }
154             else { /* not enough data to fill pad */
155 837           Copy(in_data, self->pad+self->padlen, in_data_len, unsigned char);
156 837           self->padlen += (int)in_data_len;
157 837           in_data_len = 0;
158             }
159             } /* padlen > 0 */
160              
161             /* here: a/ padlen == 1..16 && in_data_len == 0; b/ padlen == 0 && in_data_len > 0 */
162 1824 100         if (in_data_len>0) {
163 791           i = (unsigned long)(in_data_len % blen);
164 791 100         if (i>0) { /* save tail of data into pad */
165 633           Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char);
166 633           self->padlen = i;
167 633           in_data_len -= i;
168             }
169             }
170              
171 1824 100         if (in_data_len>0) {
172 297 100         if (self->padlen == 0 && self->padding_mode !=0) {
    100          
173             /* in case of padding keep full pad if no more data */
174 107           Copy(in_data+in_data_start+in_data_len-blen, self->pad, blen, unsigned char);
175 107           self->padlen = blen;
176 107           in_data_len -= blen;
177             }
178 297 100         i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len);
179 297 100         if (i > 0) {
180 295 50         out_data = (unsigned char*)SvGROW(RETVAL, out_len + i + 1) + out_len;
    50          
181 295           out_len += i;
182 295 100         if (has_tmp_block) {
183 142           Copy(tmp_block, out_data, blen, unsigned char);
184 142           out_data += blen;
185             }
186 295           rv = cbc_decrypt(in_data+in_data_start, out_data, (unsigned long)in_data_len, &self->state);
187 295 50         if (rv != CRYPT_OK) {
188 0           SvREFCNT_dec(RETVAL);
189 0           croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv));
190             }
191             }
192             } /* in_data_len>0 */
193 1527 100         else if (has_tmp_block) {
194 475 50         out_data = (unsigned char*)SvGROW(RETVAL, out_len + blen + 1) + out_len;
    50          
195 475           out_len += blen;
196 1824           Copy(tmp_block, out_data, blen, unsigned char);
197             }
198             }
199             else {
200 0           SvREFCNT_dec(RETVAL);
201 0           croak("FATAL: call start_decryt or start_encrpyt first (%d)", self->direction);
202             }
203             }
204             }
205 3505 100         if (out_len > 0) SvCUR_set(RETVAL, out_len);
206             }
207             OUTPUT:
208             RETVAL
209              
210             SV *
211             finish(Crypt::Mode::CBC self)
212             CODE:
213             {
214             unsigned char tmp_block[MAXBLOCKSIZE];
215             int rv;
216 339           unsigned long blen = (&self->state)->blocklen;
217             unsigned long padmode;
218              
219 339 100         if (self->direction == 1) {
220 153 50         if (self->padlen < 0 || self->padlen >= (int)blen) croak("FATAL: invalid padlen");
    50          
221 153 100         if (self->padding_mode != 0) {
222 90 100         if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7 | (&self->state)->blocklen; }
223 45 50         else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO | (&self->state)->blocklen; }
224 0 0         else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923 | (&self->state)->blocklen; }
225 0 0         else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO | (&self->state)->blocklen; }
226 0 0         else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS | (&self->state)->blocklen; }
227 0           else { croak("FATAL: unknown padding"); }
228 90           blen = sizeof(self->pad);
229 90           rv = padding_pad(self->pad, self->padlen, &blen, padmode);
230 90 50         if (rv != CRYPT_OK) croak("FATAL: padding_pad failed: %s", error_to_string(rv));
231 90           rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state);
232 90 50         if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv));
233             }
234             else {
235 63 50         if (self->padlen > 0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", (int)blen);
236 153           blen = 0;
237             }
238             }
239 186 50         else if (self->direction == -1) {
240 186 100         if (self->padlen > 0) {
241 123 50         if (self->padlen != (int)blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", (int)blen, self->padlen);
242 123           rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state);
243 123 50         if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv));
244 123 50         if (self->padding_mode != 0) {
245 123 100         if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7 | (&self->state)->blocklen; }
246 45 50         else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO | (&self->state)->blocklen; }
247 0 0         else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923 | (&self->state)->blocklen; }
248 0 0         else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO | (&self->state)->blocklen; }
249 0 0         else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS | (&self->state)->blocklen; }
250 0           else { croak("FATAL: unknown padding"); }
251 123           rv = padding_depad(tmp_block, &blen, padmode);
252 123 50         if (rv != CRYPT_OK) croak("FATAL: padding_depad failed: %s", error_to_string(rv));
253             }
254             else {
255             /* "no padding" == there is no need to do anything */
256             }
257             }
258             else {
259 186           blen = 0;
260             }
261             }
262             else {
263 0           croak("FATAL: invalid direction");
264             }
265              
266 339           self->direction = 0;
267 339           RETVAL = newSVpvn((char*)tmp_block, blen);
268             }
269             OUTPUT:
270             RETVAL