File Coverage

inc/CryptX_PK_Ed448.xs.inc
Criterion Covered Total %
statement 31 179 17.3
branch 12 110 10.9
condition n/a
subroutine n/a
pod n/a
total 43 289 14.8


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::PK::Ed448
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::PK::Ed448
6             _new(Class)
7             CODE:
8             {
9             int rv;
10 1           Newz(0, RETVAL, 1, struct ed448_struct);
11 1 50         if (!RETVAL) croak("FATAL: Newz failed");
12 1           RETVAL->initialized = 0;
13 1           RETVAL->pindex = find_prng("chacha20");
14 1           RETVAL->last_pid = (IV)PerlProc_getpid();
15 1 50         if (RETVAL->pindex == -1) {
16 0           zeromem(RETVAL, sizeof(*RETVAL));
17 0           Safefree(RETVAL);
18 0           croak("FATAL: find_prng('chacha20') failed");
19             }
20 1           rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
21 1 50         if (rv != CRYPT_OK) {
22 0           zeromem(RETVAL, sizeof(*RETVAL));
23 0           Safefree(RETVAL);
24 0           croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
25             }
26             }
27             OUTPUT:
28             RETVAL
29              
30             void
31             generate_key(Crypt::PK::Ed448 self)
32             PPCODE:
33             {
34             int rv;
35 1           self->initialized = 0;
36 1           cryptx_internal_pk_prng_reseed(&self->pstate, self->pindex, &self->last_pid);
37 1           rv = ed448_make_key(&self->pstate, self->pindex, &self->key);
38 1 50         if (rv != CRYPT_OK) croak("FATAL: ed448_make_key failed: %s", error_to_string(rv));
39 1           self->initialized = 1;
40 1 50         XPUSHs(ST(0)); /* return self */
41             }
42              
43             void
44             _import(Crypt::PK::Ed448 self, SV * key_data)
45             PPCODE:
46             {
47             int rv;
48 0           unsigned char *data=NULL;
49 0           STRLEN data_len=0;
50              
51 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
52 0           self->initialized = 0;
53 0           rv = ed448_import(data, (unsigned long)data_len, &self->key);
54 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import failed: %s", error_to_string(rv));
55 0           self->initialized = 1;
56 0 0         XPUSHs(ST(0)); /* return self */
57             }
58              
59             void
60             _import_pkcs8(Crypt::PK::Ed448 self, SV * key_data, SV * passwd)
61             PPCODE:
62             {
63             int rv;
64 0           unsigned char *data = NULL;
65 0           STRLEN data_len = 0;
66 0           password_ctx pw_ctx = { cryptx_internal_password_cb_getpw, cryptx_internal_password_cb_free, passwd };
67              
68 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
69 0           self->initialized = 0;
70 0 0         if (SvOK(passwd)) {
71 0           rv = ed448_import_pkcs8(data, (unsigned long)data_len, &pw_ctx, &self->key);
72             }
73             else {
74 0           rv = ed448_import_pkcs8(data, (unsigned long)data_len, NULL, &self->key);
75             }
76 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import_pkcs8 failed: %s", error_to_string(rv));
77 0           self->initialized = 1;
78 0 0         XPUSHs(ST(0)); /* return self */
79             }
80              
81             void
82             _import_pem(Crypt::PK::Ed448 self, SV * key_data, SV * passwd)
83             PPCODE:
84             {
85             int rv;
86 0           unsigned char *data = NULL;
87 0           STRLEN data_len = 0;
88 0           password_ctx pw_ctx = { cryptx_internal_password_cb_getpw, cryptx_internal_password_cb_free, passwd };
89             ltc_pka_key key_from_pem;
90              
91 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
92 0           self->initialized = 0;
93 0 0         if (SvOK(passwd)) {
94 0           rv = pem_decode_pkcs(data, (unsigned long)data_len, &key_from_pem, &pw_ctx);
95             }
96             else {
97 0           rv = pem_decode_pkcs(data, (unsigned long)data_len, &key_from_pem, NULL);
98             }
99 0 0         if (rv != CRYPT_OK) croak("FATAL: pem_decode_pkcs failed: %s", error_to_string(rv));
100 0 0         if (key_from_pem.id != LTC_PKA_ED448) croak("FATAL: pem_decode_pkcs decoded non-Ed448 key");
101 0           self->key = key_from_pem.u.ed448;
102 0           self->initialized = 1;
103 0 0         XPUSHs(ST(0)); /* return self */
104             }
105              
106             void
107             _import_x509(Crypt::PK::Ed448 self, SV * key_data)
108             PPCODE:
109             {
110             int rv;
111 0           unsigned char *data=NULL;
112 0           STRLEN data_len=0;
113              
114 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
115 0           self->initialized = 0;
116 0           rv = ed448_import_x509(data, (unsigned long)data_len, &self->key);
117 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import_x509 failed: %s", error_to_string(rv));
118 0           self->initialized = 1;
119 0 0         XPUSHs(ST(0)); /* return self */
120             }
121              
122             void
123             _import_raw(Crypt::PK::Ed448 self, SV * key, int which)
124             PPCODE:
125             {
126             int rv;
127 0           unsigned char *key_data=NULL;
128 0           STRLEN key_len=0;
129              
130 0 0         if (SvOK(key)) {
131 0           key_data = (unsigned char *)SvPVbyte(key, key_len);
132             }
133 0           self->initialized = 0;
134 0 0         if (which == 0) {
135 0           rv = ed448_import_raw(key_data, (unsigned long)key_len, PK_PUBLIC, &self->key);
136             }
137 0 0         else if (which == 1) {
138 0           rv = ed448_import_raw(key_data, (unsigned long)key_len, PK_PRIVATE, &self->key);
139             }
140             else {
141 0           croak("FATAL: import_raw invalid type '%d'", which);
142             }
143 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import_raw failed: %s", error_to_string(rv));
144 0           self->initialized = 1;
145 0 0         XPUSHs(ST(0)); /* return self */
146             }
147              
148             int
149             is_private(Crypt::PK::Ed448 self)
150             CODE:
151 0 0         if (self->initialized == 0) XSRETURN_UNDEF;
152 0 0         RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
153             OUTPUT:
154             RETVAL
155              
156             SV*
157             key2hash(Crypt::PK::Ed448 self)
158             PREINIT:
159             HV *rv_hash;
160             char buf[57 * 2 + 1];
161             unsigned long blen;
162             SV **not_used;
163             int rv;
164             CODE:
165 1 50         if (self->initialized == 0) XSRETURN_UNDEF;
166 1           rv_hash = newHV();
167             /* priv */
168 1 50         if (self->key.type == PK_PRIVATE) {
169 1           blen = sizeof(buf);
170 1           rv = base16_encode(self->key.priv, 57, buf, &blen, 0);
171 1 50         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
172 1           not_used = hv_store(rv_hash, "priv", 4, newSVpv(buf, blen), 0);
173             }
174             else {
175 0           not_used = hv_store(rv_hash, "priv", 4, newSVpvn(NULL, 0), 0); /* undef */
176             }
177             /* pub */
178 1           blen = sizeof(buf);
179 1           rv = base16_encode(self->key.pub, 57, buf, &blen, 0);
180 1 50         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
181 1           not_used = hv_store(rv_hash, "pub", 3, newSVpv(buf, blen), 0);
182             /* curve */
183 1           not_used = hv_store(rv_hash, "curve", 5, newSVpv("ed448", 0), 0);
184             LTC_UNUSED_PARAM(not_used);
185 1           RETVAL = newRV_noinc((SV*)rv_hash);
186             OUTPUT:
187             RETVAL
188              
189             SV*
190             export_key_der(Crypt::PK::Ed448 self, char * type)
191             CODE:
192             {
193             int rv;
194             unsigned char out[4096];
195 0           unsigned long int out_len = sizeof(out);
196              
197 0           RETVAL = newSVpvn(NULL, 0); /* undef */
198 0 0         if (strEQ(type, "private")) {
199 0           rv = ed448_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
200 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_export(PK_PRIVATE|PK_STD) failed: %s", error_to_string(rv));
201 0           sv_setpvn(RETVAL, (char*)out, out_len);
202             }
203 0 0         else if (strEQ(type, "public")) {
204 0           rv = ed448_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
205 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv));
206 0           sv_setpvn(RETVAL, (char*)out, out_len);
207             }
208             else {
209 0           croak("FATAL: export_key_der invalid type '%s'", type);
210             }
211 0           zeromem(out, sizeof(out));
212             }
213             OUTPUT:
214             RETVAL
215              
216             SV*
217             export_key_raw(Crypt::PK::Ed448 self, char * type)
218             CODE:
219             {
220             int rv;
221             unsigned char out[57];
222 0           unsigned long int out_len = sizeof(out);
223              
224 0           RETVAL = newSVpvn(NULL, 0); /* undef */
225 0 0         if (strEQ(type, "private")) {
226 0           rv = ed448_export(out, &out_len, PK_PRIVATE, &self->key);
227 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_export(PK_PRIVATE) failed: %s", error_to_string(rv));
228 0           sv_setpvn(RETVAL, (char*)out, out_len);
229             }
230 0 0         else if (strEQ(type, "public")) {
231 0           rv = ed448_export(out, &out_len, PK_PUBLIC, &self->key);
232 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_export(PK_PUBLIC) failed: %s", error_to_string(rv));
233 0           sv_setpvn(RETVAL, (char*)out, out_len);
234             }
235             else {
236 0           croak("FATAL: export_key_raw invalid type '%s'", type);
237             }
238 0           zeromem(out, sizeof(out));
239             }
240             OUTPUT:
241             RETVAL
242              
243             SV *
244             sign_message(Crypt::PK::Ed448 self, SV * data)
245             CODE:
246             {
247             int rv;
248 0           unsigned char buffer[114], *data_ptr = NULL;
249 0           unsigned long buffer_len = sizeof(buffer);
250 0           STRLEN data_len = 0;
251              
252 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
253 0           rv = ed448_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
254 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_sign failed: %s", error_to_string(rv));
255 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
256 0           zeromem(buffer, sizeof(buffer));
257             }
258             OUTPUT:
259             RETVAL
260              
261             int
262             verify_message(Crypt::PK::Ed448 self, SV * sig, SV * data)
263             CODE:
264             {
265             int rv, stat;
266 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL;
267 0           STRLEN data_len = 0, sig_len = 0;
268              
269 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
270 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
271 0           RETVAL = 0;
272 0           stat = 0;
273 0           rv = ed448_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len, &stat, &self->key);
274 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
275             }
276             OUTPUT:
277             RETVAL
278              
279             SV *
280             sign_message_ctx(Crypt::PK::Ed448 self, SV * data, SV * ctx)
281             CODE:
282             {
283             int rv;
284 0           unsigned char buffer[114], *data_ptr = NULL, *ctx_ptr = NULL;
285 0           unsigned long buffer_len = sizeof(buffer);
286 0           STRLEN data_len = 0, ctx_len = 0;
287              
288 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
289 0           ctx_ptr = (unsigned char *)SvPVbyte(ctx, ctx_len);
290 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
291 0           rv = ed448ctx_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
292 0           ctx_ptr, (unsigned long)ctx_len, &self->key);
293 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448ctx_sign failed: %s", error_to_string(rv));
294 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
295 0           zeromem(buffer, sizeof(buffer));
296             }
297             OUTPUT:
298             RETVAL
299              
300             int
301             verify_message_ctx(Crypt::PK::Ed448 self, SV * sig, SV * data, SV * ctx)
302             CODE:
303             {
304             int rv, stat;
305 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL, *ctx_ptr = NULL;
306 0           STRLEN data_len = 0, sig_len = 0, ctx_len = 0;
307              
308 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
309 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
310 0           ctx_ptr = (unsigned char *)SvPVbyte(ctx, ctx_len);
311 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
312 0           RETVAL = 0;
313 0           stat = 0;
314 0           rv = ed448ctx_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len,
315 0           ctx_ptr, (unsigned long)ctx_len, &stat, &self->key);
316 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
317             }
318             OUTPUT:
319             RETVAL
320              
321             SV *
322             sign_message_ph(Crypt::PK::Ed448 self, SV * data, ...)
323             CODE:
324             {
325             int rv;
326 0           unsigned char buffer[114], *data_ptr = NULL, *ctx_ptr = NULL;
327 0           unsigned long buffer_len = sizeof(buffer);
328 0           STRLEN data_len = 0, ctx_len = 0;
329              
330 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
331 0 0         if (items > 2 && SvOK(ST(2))) {
    0          
332 0           ctx_ptr = (unsigned char *)SvPVbyte(ST(2), ctx_len);
333 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
334             }
335 0           rv = ed448ph_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
336 0           ctx_ptr, (unsigned long)ctx_len, &self->key);
337 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448ph_sign failed: %s", error_to_string(rv));
338 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
339 0           zeromem(buffer, sizeof(buffer));
340             }
341             OUTPUT:
342             RETVAL
343              
344             int
345             verify_message_ph(Crypt::PK::Ed448 self, SV * sig, SV * data, ...)
346             CODE:
347             {
348             int rv, stat;
349 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL, *ctx_ptr = NULL;
350 0           STRLEN data_len = 0, sig_len = 0, ctx_len = 0;
351              
352 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
353 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
354 0 0         if (items > 3 && SvOK(ST(3))) {
    0          
355 0           ctx_ptr = (unsigned char *)SvPVbyte(ST(3), ctx_len);
356 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
357             }
358 0           RETVAL = 0;
359 0           stat = 0;
360 0           rv = ed448ph_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len,
361 0           ctx_ptr, (unsigned long)ctx_len, &stat, &self->key);
362 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
363             }
364             OUTPUT:
365             RETVAL
366              
367             void
368             DESTROY(Crypt::PK::Ed448 self)
369             CODE:
370 1 50         if (self->pindex >= 0 && prng_is_valid(self->pindex) == CRYPT_OK && prng_descriptor[self->pindex].done) {
    50          
    50          
371 1           prng_descriptor[self->pindex].done(&self->pstate);
372             }
373 1           zeromem(self, sizeof(*self));
374 1           Safefree(self);