File Coverage

inc/CryptX_Mode_ECB.xs.inc
Criterion Covered Total %
statement 133 156 85.2
branch 96 146 65.7
condition n/a
subroutine n/a
pod n/a
total 229 302 75.8


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