File Coverage

inc/CryptX_PK_Ed448.xs.inc
Criterion Covered Total %
statement 32 182 17.5
branch 12 110 10.9
condition n/a
subroutine n/a
pod n/a
total 44 292 15.0


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) {
101 0           pka_key_free(&key_from_pem);
102 0           croak("FATAL: pem_decode_pkcs decoded non-Ed448 key");
103             }
104 0           self->key = key_from_pem.u.ed448;
105 0           self->initialized = 1;
106 0 0         XPUSHs(ST(0)); /* return self */
107             }
108              
109             void
110             _import_x509(Crypt::PK::Ed448 self, SV * key_data)
111             PPCODE:
112             {
113             int rv;
114 0           unsigned char *data=NULL;
115 0           STRLEN data_len=0;
116              
117 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
118 0           self->initialized = 0;
119 0           rv = ed448_import_x509(data, (unsigned long)data_len, &self->key);
120 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import_x509 failed: %s", error_to_string(rv));
121 0           self->initialized = 1;
122 0 0         XPUSHs(ST(0)); /* return self */
123             }
124              
125             void
126             _import_raw(Crypt::PK::Ed448 self, SV * key, int which)
127             PPCODE:
128             {
129             int rv;
130 0           unsigned char *key_data=NULL;
131 0           STRLEN key_len=0;
132              
133 0 0         if (SvOK(key)) {
134 0           key_data = (unsigned char *)SvPVbyte(key, key_len);
135             }
136 0           self->initialized = 0;
137 0 0         if (which == 0) {
138 0           rv = ed448_import_raw(key_data, (unsigned long)key_len, PK_PUBLIC, &self->key);
139             }
140 0 0         else if (which == 1) {
141 0           rv = ed448_import_raw(key_data, (unsigned long)key_len, PK_PRIVATE, &self->key);
142             }
143             else {
144 0           croak("FATAL: import_raw invalid type '%d'", which);
145             }
146 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448_import_raw failed: %s", error_to_string(rv));
147 0           self->initialized = 1;
148 0 0         XPUSHs(ST(0)); /* return self */
149             }
150              
151             int
152             is_private(Crypt::PK::Ed448 self)
153             CODE:
154 0 0         if (self->initialized == 0) XSRETURN_UNDEF;
155 0 0         RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
156             OUTPUT:
157             RETVAL
158              
159             SV*
160             key2hash(Crypt::PK::Ed448 self)
161             PREINIT:
162             HV *rv_hash;
163             char buf[57 * 2 + 1];
164             unsigned long blen;
165             SV **not_used;
166             int rv;
167             CODE:
168 1 50         if (self->initialized == 0) XSRETURN_UNDEF;
169 1           rv_hash = newHV();
170             /* priv */
171 1 50         if (self->key.type == PK_PRIVATE) {
172 1           blen = sizeof(buf);
173 1           rv = base16_encode(self->key.priv, 57, buf, &blen, 0);
174 1 50         if (rv != CRYPT_OK) { zeromem(buf, sizeof(buf)); croak("FATAL: base16_encode failed: %s", error_to_string(rv)); }
175 1           not_used = hv_store(rv_hash, "priv", 4, newSVpv(buf, blen), 0);
176             }
177             else {
178 0           not_used = hv_store(rv_hash, "priv", 4, newSVpvn(NULL, 0), 0); /* undef */
179             }
180             /* pub */
181 1           blen = sizeof(buf);
182 1           rv = base16_encode(self->key.pub, 57, buf, &blen, 0);
183 1 50         if (rv != CRYPT_OK) { zeromem(buf, sizeof(buf)); croak("FATAL: base16_encode failed: %s", error_to_string(rv)); }
184 1           not_used = hv_store(rv_hash, "pub", 3, newSVpv(buf, blen), 0);
185             /* curve */
186 1           not_used = hv_store(rv_hash, "curve", 5, newSVpv("ed448", 0), 0);
187             LTC_UNUSED_PARAM(not_used);
188 1           zeromem(buf, sizeof(buf));
189 1           RETVAL = newRV_noinc((SV*)rv_hash);
190             OUTPUT:
191             RETVAL
192              
193             SV*
194             export_key_der(Crypt::PK::Ed448 self, char * type)
195             CODE:
196             {
197             int rv;
198             unsigned char out[4096];
199 0           unsigned long int out_len = sizeof(out);
200              
201 0           RETVAL = newSVpvn(NULL, 0); /* undef */
202 0 0         if (strEQ(type, "private")) {
203 0           rv = ed448_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
204 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: ed448_export(PK_PRIVATE|PK_STD) failed: %s", error_to_string(rv)); }
205 0           sv_setpvn(RETVAL, (char*)out, out_len);
206             }
207 0 0         else if (strEQ(type, "public")) {
208 0           rv = ed448_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
209 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: ed448_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv)); }
210 0           sv_setpvn(RETVAL, (char*)out, out_len);
211             }
212             else {
213 0           croak("FATAL: export_key_der invalid type '%s'", type);
214             }
215 0           zeromem(out, sizeof(out));
216             }
217             OUTPUT:
218             RETVAL
219              
220             SV*
221             export_key_raw(Crypt::PK::Ed448 self, char * type)
222             CODE:
223             {
224             int rv;
225             unsigned char out[57];
226 0           unsigned long int out_len = sizeof(out);
227              
228 0           RETVAL = newSVpvn(NULL, 0); /* undef */
229 0 0         if (strEQ(type, "private")) {
230 0           rv = ed448_export(out, &out_len, PK_PRIVATE, &self->key);
231 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: ed448_export(PK_PRIVATE) failed: %s", error_to_string(rv)); }
232 0           sv_setpvn(RETVAL, (char*)out, out_len);
233             }
234 0 0         else if (strEQ(type, "public")) {
235 0           rv = ed448_export(out, &out_len, PK_PUBLIC, &self->key);
236 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: ed448_export(PK_PUBLIC) failed: %s", error_to_string(rv)); }
237 0           sv_setpvn(RETVAL, (char*)out, out_len);
238             }
239             else {
240 0           croak("FATAL: export_key_raw invalid type '%s'", type);
241             }
242 0           zeromem(out, sizeof(out));
243             }
244             OUTPUT:
245             RETVAL
246              
247             SV *
248             sign_message(Crypt::PK::Ed448 self, SV * data)
249             CODE:
250             {
251             int rv;
252 0           unsigned char buffer[114], *data_ptr = NULL;
253 0           unsigned long buffer_len = sizeof(buffer);
254 0           STRLEN data_len = 0;
255              
256 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
257 0           rv = ed448_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
258 0 0         if (rv != CRYPT_OK) { zeromem(buffer, sizeof(buffer)); croak("FATAL: ed448_sign failed: %s", error_to_string(rv)); }
259 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
260 0           zeromem(buffer, sizeof(buffer));
261             }
262             OUTPUT:
263             RETVAL
264              
265             int
266             verify_message(Crypt::PK::Ed448 self, SV * sig, SV * data)
267             CODE:
268             {
269             int rv, stat;
270 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL;
271 0           STRLEN data_len = 0, sig_len = 0;
272              
273 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
274 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
275 0           RETVAL = 0;
276 0           stat = 0;
277 0           rv = ed448_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len, &stat, &self->key);
278 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
279             }
280             OUTPUT:
281             RETVAL
282              
283             SV *
284             sign_message_ctx(Crypt::PK::Ed448 self, SV * data, SV * ctx)
285             CODE:
286             {
287             int rv;
288 0           unsigned char buffer[114], *data_ptr = NULL, *ctx_ptr = NULL;
289 0           unsigned long buffer_len = sizeof(buffer);
290 0           STRLEN data_len = 0, ctx_len = 0;
291              
292 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
293 0           ctx_ptr = (unsigned char *)SvPVbyte(ctx, ctx_len);
294 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
295 0           rv = ed448ctx_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
296 0           ctx_ptr, (unsigned long)ctx_len, &self->key);
297 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448ctx_sign failed: %s", error_to_string(rv));
298 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
299 0           zeromem(buffer, sizeof(buffer));
300             }
301             OUTPUT:
302             RETVAL
303              
304             int
305             verify_message_ctx(Crypt::PK::Ed448 self, SV * sig, SV * data, SV * ctx)
306             CODE:
307             {
308             int rv, stat;
309 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL, *ctx_ptr = NULL;
310 0           STRLEN data_len = 0, sig_len = 0, ctx_len = 0;
311              
312 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
313 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
314 0           ctx_ptr = (unsigned char *)SvPVbyte(ctx, ctx_len);
315 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
316 0           RETVAL = 0;
317 0           stat = 0;
318 0           rv = ed448ctx_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len,
319 0           ctx_ptr, (unsigned long)ctx_len, &stat, &self->key);
320 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
321             }
322             OUTPUT:
323             RETVAL
324              
325             SV *
326             sign_message_ph(Crypt::PK::Ed448 self, SV * data, ...)
327             CODE:
328             {
329             int rv;
330 0           unsigned char buffer[114], *data_ptr = NULL, *ctx_ptr = NULL;
331 0           unsigned long buffer_len = sizeof(buffer);
332 0           STRLEN data_len = 0, ctx_len = 0;
333              
334 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
335 0 0         if (items > 2 && SvOK(ST(2))) {
    0          
336 0           ctx_ptr = (unsigned char *)SvPVbyte(ST(2), ctx_len);
337 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
338             }
339 0           rv = ed448ph_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
340 0           ctx_ptr, (unsigned long)ctx_len, &self->key);
341 0 0         if (rv != CRYPT_OK) croak("FATAL: ed448ph_sign failed: %s", error_to_string(rv));
342 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
343 0           zeromem(buffer, sizeof(buffer));
344             }
345             OUTPUT:
346             RETVAL
347              
348             int
349             verify_message_ph(Crypt::PK::Ed448 self, SV * sig, SV * data, ...)
350             CODE:
351             {
352             int rv, stat;
353 0           unsigned char *data_ptr = NULL, *sig_ptr = NULL, *ctx_ptr = NULL;
354 0           STRLEN data_len = 0, sig_len = 0, ctx_len = 0;
355              
356 0           data_ptr = (unsigned char *)SvPVbyte(data, data_len);
357 0           sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
358 0 0         if (items > 3 && SvOK(ST(3))) {
    0          
359 0           ctx_ptr = (unsigned char *)SvPVbyte(ST(3), ctx_len);
360 0 0         if (ctx_len > 255) croak("FATAL: context must be at most 255 bytes");
361             }
362 0           RETVAL = 0;
363 0           stat = 0;
364 0           rv = ed448ph_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len,
365 0           ctx_ptr, (unsigned long)ctx_len, &stat, &self->key);
366 0 0         if (rv == CRYPT_OK && stat == 1) RETVAL = 1;
    0          
367             }
368             OUTPUT:
369             RETVAL
370              
371             void
372             DESTROY(Crypt::PK::Ed448 self)
373             CODE:
374 1 50         if (self->pindex >= 0 && prng_is_valid(self->pindex) == CRYPT_OK && prng_descriptor[self->pindex].done) {
    50          
    50          
375 1           prng_descriptor[self->pindex].done(&self->pstate);
376             }
377 1           zeromem(self, sizeof(*self));
378 1           Safefree(self);