File Coverage

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