File Coverage

inc/CryptX_PK_DH.xs.inc
Criterion Covered Total %
statement 112 145 77.2
branch 65 140 46.4
condition n/a
subroutine n/a
pod n/a
total 177 285 62.1


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::PK::DH
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::PK::DH
6             _new(Class)
7             CODE:
8             {
9             int rv;
10 35           Newz(0, RETVAL, 1, struct dh_struct);
11 35 50         if (!RETVAL) croak("FATAL: Newz failed");
12 35           RETVAL->key.type = -1;
13 35           RETVAL->pindex = find_prng("chacha20");
14 35 50         if (RETVAL->pindex == -1) {
15 0           Safefree(RETVAL);
16 0           croak("FATAL: find_prng('chacha20') failed");
17             }
18 35           rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
19 35 50         if (rv != CRYPT_OK) {
20 0           Safefree(RETVAL);
21 0           croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
22             }
23             }
24             OUTPUT:
25             RETVAL
26              
27             void
28             _generate_key_size(Crypt::PK::DH self, int groupsize=256)
29             PPCODE:
30             {
31             int rv;
32 1           rv = dh_set_pg_groupsize(groupsize, &self->key);
33 1 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_pg_groupsize failed: %s", error_to_string(rv));
34 1           rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
35 1 50         if (rv != CRYPT_OK) croak("FATAL: dh_generate_key failed: %s", error_to_string(rv));
36 1 50         XPUSHs(ST(0)); /* return self */
37             }
38              
39             void
40             _generate_key_gp(Crypt::PK::DH self, char *g, char *p)
41             PPCODE:
42             {
43             int rv;
44             unsigned char pbin[1024], gbin[512];
45 4           unsigned long plen=sizeof(pbin), glen=sizeof(gbin);
46              
47 4 50         if (p && strlen(p) > 0 && g && strlen(g) > 0) {
    50          
    50          
    50          
48 4           rv = radix_to_bin(p, 16, pbin, &plen);
49 4 50         if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv));
50 4           rv = radix_to_bin(g, 16, gbin, &glen);
51 4 50         if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(g) failed: %s", error_to_string(rv));
52              
53 4           rv = dh_set_pg(pbin, plen, gbin, glen, &self->key);
54 4 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_pg failed: %s", error_to_string(rv));
55 4           rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
56 4 50         if (rv != CRYPT_OK) croak("FATAL: dh_generate_key failed: %s", error_to_string(rv));
57             }
58              
59 4 50         XPUSHs(ST(0)); /* return self */
60             }
61              
62             void
63             _generate_key_dhparam(Crypt::PK::DH self, SV * dhparam)
64             PPCODE:
65             {
66             int rv;
67 2           unsigned char *data=NULL;
68 2           STRLEN data_len=0;
69 2 50         data = (unsigned char *)SvPVbyte(dhparam, data_len);
70             /* load d p q */
71 2           rv = dh_set_pg_dhparam(data, (unsigned long)data_len, &self->key);
72 2 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_pg_dhparam failed: %s", error_to_string(rv));
73             /* gen the key */
74 2           rv = dh_generate_key(&self->pstate, self->pindex, &self->key);
75 2 50         if (rv != CRYPT_OK) croak("FATAL: dh_generate_key failed: %s", error_to_string(rv));
76 2 50         XPUSHs(ST(0)); /* return self */
77             }
78              
79             void
80             _import(Crypt::PK::DH self, SV * key_data)
81             PPCODE:
82             {
83             int rv;
84 24           unsigned char *data=NULL;
85 24           STRLEN data_len=0;
86              
87 24 50         data = (unsigned char *)SvPVbyte(key_data, data_len);
88 24 50         if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
89 24           rv = dh_import(data, (unsigned long)data_len, &self->key);
90 24 50         if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv));
91 24 50         XPUSHs(ST(0)); /* return self */
92             }
93              
94             void
95             _import_raw(Crypt::PK::DH self, SV * raw_key, int type, char * g, char * p)
96             PPCODE:
97             {
98             int rv;
99 4           unsigned char *data=NULL;
100 4           STRLEN data_len=0;
101             unsigned char pbin[1024], gbin[512];
102 4           unsigned long plen=sizeof(pbin), glen=sizeof(gbin);
103              
104 4 50         data = (unsigned char *)SvPVbyte(raw_key, data_len);
105 4 50         if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
106              
107 4 50         if (p && strlen(p) > 0 && g && strlen(g) > 0) {
    50          
    50          
    50          
108 4           rv = radix_to_bin(p, 16, pbin, &plen);
109 4 50         if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv));
110 4           rv = radix_to_bin(g, 16, gbin, &glen);
111 4 50         if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(g) failed: %s", error_to_string(rv));
112              
113 4           rv = dh_set_pg(pbin, plen, gbin, glen, &self->key);
114 4 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_pg failed: %s", error_to_string(rv));
115              
116 4 100         if (type == 0) {
117             /* public */
118 2           rv = dh_set_key(data, (unsigned long)data_len, PK_PUBLIC, &self->key);
119 2 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_key failed: %s", error_to_string(rv));
120             }
121 2 50         else if (type == 1) {
122             /* private */
123 2           rv = dh_set_key(data, (unsigned long)data_len, PK_PRIVATE, &self->key);
124 2 50         if (rv != CRYPT_OK) croak("FATAL: dh_set_key failed: %s", error_to_string(rv));
125             }
126             else {
127 0           croak("FATAL: import_raw invalid type '%d'", type);
128             }
129             }
130              
131 4 50         XPUSHs(ST(0)); /* return self */
132             }
133              
134             int
135             is_private(Crypt::PK::DH self)
136             CODE:
137 21 50         if (self->key.type == -1) XSRETURN_UNDEF;
138 21           RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
139             OUTPUT:
140             RETVAL
141              
142             int
143             size(Crypt::PK::DH self)
144             CODE:
145 2 50         if (self->key.type == -1) XSRETURN_UNDEF;
146 2           RETVAL = dh_get_groupsize(&self->key);
147             OUTPUT:
148             RETVAL
149              
150             SV*
151             key2hash(Crypt::PK::DH self)
152             PREINIT:
153             HV *rv_hash;
154             long siz;
155             char buf[20001];
156             SV **not_used;
157             CODE:
158 2 50         if (self->key.type == -1) XSRETURN_UNDEF;
159 2           rv_hash = newHV();
160             /* x */
161 2 50         siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0;
162 2 50         if (siz>10000) {
163 0           croak("FATAL: key2hash failed - 'x' too big number");
164             }
165 2 50         if (siz>0) {
166 2           cryptx_internal_mp2hex_with_leading_zero(self->key.x, buf, 20000, 0);
167 2           not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
168             }
169             else{
170 0           not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
171             }
172             /* y */
173 2 50         siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0;
174 2 50         if (siz>10000) {
175 0           croak("FATAL: key2hash failed - 'y' too big number");
176             }
177 2 50         if (siz>0) {
178 2           cryptx_internal_mp2hex_with_leading_zero(self->key.y, buf, 20000, 0);
179 2           not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
180             }
181             else{
182 0           not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
183             }
184             /* p */
185 2 50         siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0;
186 2 50         if (siz>10000) {
187 0           croak("FATAL: key2hash failed - 'p' too big number");
188             }
189 2 50         if (siz>0) {
190 2           cryptx_internal_mp2hex_with_leading_zero(self->key.prime, buf, 20000, 0);
191 2           not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
192             }
193             else {
194 0           not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
195             }
196              
197             /* g */
198 2 50         siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0;
199 2 50         if (siz>10000) {
200 0           croak("FATAL: key2hash failed - 'g' too big number");
201             }
202 2 50         if (siz>0) {
203 2           cryptx_internal_mp2hex_with_leading_zero(self->key.base, buf, 20000, 0);
204 2           not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
205             }
206             else {
207 0           not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
208             }
209             /* size */
210 2           not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_groupsize(&self->key)), 0);
211             /* type */
212 2           not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
213             LTC_UNUSED_PARAM(not_used);
214 2           RETVAL = newRV_noinc((SV*)rv_hash);
215             OUTPUT:
216             RETVAL
217              
218             SV*
219             params2hash(Crypt::PK::DH self)
220             PREINIT:
221             HV *rv_hash;
222             long siz;
223             char buf[20001];
224             SV **not_used;
225             CODE:
226 0 0         if (self->key.type == -1) XSRETURN_UNDEF;
227 0           rv_hash = newHV();
228             /* p */
229 0 0         siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0;
230 0 0         if (siz>10000) {
231 0           croak("FATAL: key2hash failed - 'p' too big number");
232             }
233 0 0         if (siz>0) {
234 0           cryptx_internal_mp2hex_with_leading_zero(self->key.prime, buf, 20000, 0);
235 0           not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
236             }
237             else {
238 0           not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
239             }
240              
241             /* g */
242 0 0         siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0;
243 0 0         if (siz>10000) {
244 0           croak("FATAL: key2hash failed - 'g' too big number");
245             }
246 0 0         if (siz>0) {
247 0           cryptx_internal_mp2hex_with_leading_zero(self->key.base, buf, 20000, 0);
248 0           not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
249             }
250             else {
251 0           not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
252             }
253 0 0         if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
254 0           RETVAL = newRV_noinc((SV*)rv_hash);
255             OUTPUT:
256             RETVAL
257              
258             SV *
259             export_key(Crypt::PK::DH self, char * type)
260             CODE:
261             {
262             int rv;
263 14           unsigned long int out_len = 4096;
264             unsigned char out[4096];
265              
266 14           RETVAL = newSVpvn(NULL, 0); /* undef */
267 14 100         if (strnEQ(type, "private", 7)) {
268 7           rv = dh_export(out, &out_len, PK_PRIVATE, &self->key);
269 7 50         if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PRIVATE) failed: %s", error_to_string(rv));
270 7           RETVAL = newSVpvn((char*)out, out_len);
271             }
272 7 50         else if (strnEQ(type, "public", 6)) {
273 7           rv = dh_export(out, &out_len, PK_PUBLIC, &self->key);
274 7 50         if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PUBLIC) failed: %s", error_to_string(rv));
275 7           RETVAL = newSVpvn((char*)out, out_len);
276             }
277             else {
278 0           croak("FATAL: export_key_der invalid type '%s'", type);
279             }
280             }
281             OUTPUT:
282             RETVAL
283              
284             SV *
285             shared_secret(Crypt::PK::DH self, Crypt::PK::DH pubkey)
286             CODE:
287             {
288             int rv;
289 10           unsigned long buffer_len = 1024;
290             unsigned char buffer[1024];
291              
292 10           rv = dh_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
293 10 50         if (rv != CRYPT_OK) croak("FATAL: dh_shared_secret failed: %s", error_to_string(rv));
294 10           RETVAL = newSVpvn((char*)buffer, buffer_len);
295             }
296             OUTPUT:
297             RETVAL
298              
299             SV *
300             export_key_raw(Crypt::PK::DH self, char * type)
301             CODE:
302             {
303             int rv;
304             unsigned char out[1024];
305 3           unsigned long out_len = 1024;
306              
307 3           RETVAL = newSVpvn(NULL, 0); /* undef */
308 3 100         if (strnEQ(type, "private", 7)) {
309 1           rv = dh_export_key(out, &out_len, PK_PRIVATE, &self->key);
310 1 50         if (rv != CRYPT_OK) croak("FATAL: dh_export_key(PK_PRIVATE) failed: %s", error_to_string(rv));
311 1           RETVAL = newSVpvn((char*)out, out_len);
312             }
313 2 50         else if (strnEQ(type, "public", 6)) {
314 2           rv = dh_export_key(out, &out_len, PK_PUBLIC, &self->key);
315 2 50         if (rv != CRYPT_OK) croak("FATAL: dh_export_key(PK_PUBLIC) failed: %s", error_to_string(rv));
316 2           RETVAL = newSVpvn((char*)out, out_len);
317             }
318             else {
319 0           croak("FATAL: export_key_raw: invalid type '%s'", type);
320             }
321             }
322             OUTPUT:
323             RETVAL
324              
325             void
326             DESTROY(Crypt::PK::DH self)
327             CODE:
328 35 50         if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
329 35           Safefree(self);