File Coverage

inc/CryptX_AuthEnc_EAX.xs.inc
Criterion Covered Total %
statement 87 107 81.3
branch 59 126 46.8
condition n/a
subroutine n/a
pod n/a
total 146 233 62.6


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::AuthEnc::EAX
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::AuthEnc::EAX
6             new(Class, char * cipher_name, SV * key, SV * nonce, SV * adata=&PL_sv_undef)
7             CODE:
8             {
9 19           STRLEN k_len=0;
10 19           unsigned char *k=NULL;
11 19           unsigned char *n=NULL;
12 19           STRLEN n_len=0;
13 19           unsigned char *h=NULL;
14 19           STRLEN h_len=0;
15             int rv, id;
16              
17 19 50         if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
18 19 50         k = (unsigned char *) SvPVbyte(key, k_len);
19 19 50         if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
20 19 50         n = (unsigned char *) SvPVbyte(nonce, n_len);
21 19 50         if (SvOK(adata)) { /* adata is optional param */
    50          
    50          
22 0 0         if (!SvPOK(adata)) croak("FATAL: adata must be string/buffer scalar");
23 0 0         h = (unsigned char *) SvPVbyte(adata, h_len);
24             }
25              
26 19           id = cryptx_internal_find_cipher(cipher_name);
27 19 50         if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
28              
29 19           Newz(0, RETVAL, 1, eax_state);
30 19 50         if (!RETVAL) croak("FATAL: Newz failed");
31              
32 19           rv = eax_init(RETVAL, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len);
33 19 50         if (rv != CRYPT_OK) {
34 0           Safefree(RETVAL);
35 0           croak("FATAL: eax setup failed: %s", error_to_string(rv));
36             }
37             }
38             OUTPUT:
39             RETVAL
40              
41             void
42             DESTROY(Crypt::AuthEnc::EAX self)
43             CODE:
44 19           Safefree(self);
45              
46             Crypt::AuthEnc::EAX
47             clone(Crypt::AuthEnc::EAX self)
48             CODE:
49 0           Newz(0, RETVAL, 1, eax_state);
50 0 0         if (!RETVAL) croak("FATAL: Newz failed");
51 0           Copy(self, RETVAL, 1, eax_state);
52             OUTPUT:
53             RETVAL
54              
55             SV *
56             encrypt_add(Crypt::AuthEnc::EAX self, SV * data)
57             CODE:
58             {
59             int rv;
60             STRLEN in_data_len;
61             unsigned char *in_data, *out_data;
62              
63 10 50         in_data = (unsigned char *)SvPVbyte(data, in_data_len);
64 10 100         if (in_data_len == 0) {
65 4           RETVAL = newSVpvn("", 0);
66             }
67             else {
68 6           RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
69 6           SvPOK_only(RETVAL);
70 6           SvCUR_set(RETVAL, in_data_len);
71 6           out_data = (unsigned char *)SvPVX(RETVAL);
72 6           rv = eax_encrypt(self, in_data, out_data, (unsigned long)in_data_len);
73 6 50         if (rv != CRYPT_OK) {
74 0           SvREFCNT_dec(RETVAL);
75 0           croak("FATAL: eax_encrypt failed: %s", error_to_string(rv));
76             }
77             }
78             }
79             OUTPUT:
80             RETVAL
81              
82             SV *
83             decrypt_add(Crypt::AuthEnc::EAX self, SV * data)
84             CODE:
85             {
86             int rv;
87             STRLEN in_data_len;
88             unsigned char *in_data, *out_data;
89              
90 29 100         in_data = (unsigned char *)SvPVbyte(data, in_data_len);
91 29 100         if (in_data_len == 0) {
92 4           RETVAL = newSVpvn("", 0);
93             }
94             else {
95 25           RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
96 25           SvPOK_only(RETVAL);
97 25           SvCUR_set(RETVAL, in_data_len);
98 25           out_data = (unsigned char *)SvPVX(RETVAL);
99 25           rv = eax_decrypt(self, in_data, out_data, (unsigned long)in_data_len);
100 25 50         if (rv != CRYPT_OK) {
101 0           SvREFCNT_dec(RETVAL);
102 0           croak("FATAL: eax_decrypt failed: %s", error_to_string(rv));
103             }
104             }
105             }
106             OUTPUT:
107             RETVAL
108              
109             void
110             encrypt_done(Crypt::AuthEnc::EAX self)
111             PPCODE:
112             {
113             int rv;
114             unsigned char tag[MAXBLOCKSIZE];
115 9           unsigned long tag_len = sizeof(tag);
116              
117 9           rv = eax_done(self, tag, &tag_len);
118 9 50         if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
119 9 50         XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
120             }
121              
122             void
123             decrypt_done(Crypt::AuthEnc::EAX self, ...)
124             PPCODE:
125             {
126             int rv;
127             unsigned char tag[MAXBLOCKSIZE];
128 10           unsigned long tag_len = sizeof(tag);
129             STRLEN expected_tag_len;
130             unsigned char *expected_tag;
131              
132 10           rv = eax_done(self, tag, &tag_len);
133 10 50         if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
134 10 50         if (items == 1) {
135 10 50         XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
136             }
137             else {
138 0 0         if (!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
139 0 0         expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
140 0 0         if (expected_tag_len!=tag_len) {
141 0 0         XPUSHs(sv_2mortal(newSViv(0))); /* false */
142             }
143 0 0         else if (memNE(expected_tag, tag, tag_len)) {
144 0 0         XPUSHs(sv_2mortal(newSViv(0))); /* false */
145             }
146             else {
147 0 0         XPUSHs(sv_2mortal(newSViv(1))); /* true */
148             }
149             }
150             }
151              
152             void
153             adata_add(Crypt::AuthEnc::EAX self, SV * adata)
154             PPCODE:
155             {
156             STRLEN h_len;
157             int rv;
158             unsigned char *h;
159 23 50         h = (unsigned char *)SvPVbyte(adata, h_len);
160 23           rv = eax_addheader(self, h, (unsigned long)h_len);
161 23 50         if (rv != CRYPT_OK) croak("FATAL: eax_addheader failed: %s", error_to_string(rv));
162 23 50         XPUSHs(ST(0)); /* return self */
163             }
164              
165             void
166             eax_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, SV *plaintext)
167             PPCODE:
168             {
169 10           STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0;
170 10           unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL;
171             int rv, id;
172             unsigned char tag[MAXBLOCKSIZE];
173 10           unsigned long tag_len = sizeof(tag);
174             SV *output;
175              
176 10 50         if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len);
    50          
177 10 50         if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len);
    50          
178 10 50         if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len);
    50          
179 10 50         if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len);
    50          
180              
181 10           id = cryptx_internal_find_cipher(cipher_name);
182 10 50         if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
183 10 100         output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */
184 10           SvPOK_only(output);
185 10           SvCUR_set(output, pt_len);
186              
187 10           rv = eax_encrypt_authenticate_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len,
188             h, (unsigned long)h_len, pt, (unsigned long)pt_len,
189 10           (unsigned char *)SvPVX(output), tag, &tag_len);
190              
191 10 50         if (rv != CRYPT_OK) {
192 0           SvREFCNT_dec(output);
193 0           croak("FATAL: ccm_memory failed: %s", error_to_string(rv));
194             }
195 10 50         XPUSHs(sv_2mortal(output));
196 10 50         XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
197             }
198              
199             void
200             eax_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv)
201             PPCODE:
202             {
203 12           STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0;
204 12           unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL;
205 12           int rv, id, stat = 0;
206             unsigned char tag[MAXBLOCKSIZE];
207             unsigned long tag_len;
208             SV *output;
209              
210 12 50         if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len);
    50          
211 12 50         if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len);
    50          
212 12 50         if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len);
    50          
213 12 50         if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len);
    50          
214 12 50         if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len);
    50          
215              
216 12           id = cryptx_internal_find_cipher(cipher_name);
217 12 50         if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
218 12 100         output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */
219 12           SvPOK_only(output);
220 12           SvCUR_set(output, ct_len);
221 12           tag_len = (unsigned long)t_len;
222 12           Copy(t, tag, t_len, unsigned char);
223              
224 12           rv = eax_decrypt_verify_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len,
225 12           ct, (unsigned long)ct_len, (unsigned char *)SvPVX(output), tag, tag_len, &stat);
226              
227 12 50         if (rv != CRYPT_OK || stat != 1) {
    100          
228 2           SvREFCNT_dec(output);
229 2 50         XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */
230             }
231             else {
232 10 50         XPUSHs(sv_2mortal(output));
233             }
234             }