File Coverage

inc/CryptX_AuthEnc_CCM.xs.inc
Criterion Covered Total %
statement 87 111 78.3
branch 58 126 46.0
condition n/a
subroutine n/a
pod n/a
total 145 237 61.1


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