File Coverage

inc/CryptX_Mode_ECB.xs.inc
Criterion Covered Total %
statement 128 154 83.1
branch 95 142 66.9
condition n/a
subroutine n/a
pod n/a
total 223 296 75.3


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