File Coverage

inc/CryptX_PK_X448.xs.inc
Criterion Covered Total %
statement 44 122 36.0
branch 17 78 21.7
condition n/a
subroutine n/a
pod n/a
total 61 200 30.5


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::PK::X448
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::PK::X448
6             _new(Class)
7             CODE:
8             {
9             int rv;
10 3           Newz(0, RETVAL, 1, struct x448_struct);
11 3 50         if (!RETVAL) croak("FATAL: Newz failed");
12 3           RETVAL->initialized = 0;
13 3           RETVAL->pindex = find_prng("chacha20");
14 3           RETVAL->last_pid = (IV)PerlProc_getpid();
15 3 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 3           rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
21 3 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::X448 self)
32             PPCODE:
33             {
34             int rv;
35 2           self->initialized = 0;
36 2           cryptx_internal_pk_prng_reseed(&self->pstate, self->pindex, &self->last_pid);
37 2           rv = x448_make_key(&self->pstate, self->pindex, &self->key);
38 2 50         if (rv != CRYPT_OK) croak("FATAL: x448_make_key failed: %s", error_to_string(rv));
39 2           self->initialized = 1;
40 2 50         XPUSHs(ST(0)); /* return self */
41             }
42              
43             void
44             _import(Crypt::PK::X448 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 = x448_import(data, (unsigned long)data_len, &self->key);
54 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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::X448 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 = x448_import_pkcs8(data, (unsigned long)data_len, &pw_ctx, &self->key);
72             }
73             else {
74 0           rv = x448_import_pkcs8(data, (unsigned long)data_len, NULL, &self->key);
75             }
76 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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::X448 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_X448) croak("FATAL: pem_decode_pkcs decoded non-X448 key");
101 0           self->key = key_from_pem.u.x448;
102 0           self->initialized = 1;
103 0 0         XPUSHs(ST(0)); /* return self */
104             }
105              
106             void
107             _import_x509(Crypt::PK::X448 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 = x448_import_x509(data, (unsigned long)data_len, &self->key);
117 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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::X448 self, SV * key, int which)
124             PPCODE:
125             {
126             int rv;
127 1           unsigned char *key_data=NULL;
128 1           STRLEN key_len=0;
129              
130 1 50         if (SvOK(key)) {
131 1           key_data = (unsigned char *)SvPVbyte(key, key_len);
132             }
133 1           self->initialized = 0;
134 1 50         if (which == 0) {
135 1           rv = x448_import_raw(key_data, (unsigned long)key_len, PK_PUBLIC, &self->key);
136             }
137 0 0         else if (which == 1) {
138 0           rv = x448_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 1 50         if (rv != CRYPT_OK) croak("FATAL: x448_import_raw failed: %s", error_to_string(rv));
144 1           self->initialized = 1;
145 1 50         XPUSHs(ST(0)); /* return self */
146             }
147              
148             int
149             is_private(Crypt::PK::X448 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::X448 self)
158             PREINIT:
159             HV *rv_hash;
160             char buf[56 * 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, 56, 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, 56, 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("x448", 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::X448 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 = x448_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
200 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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 = x448_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
205 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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::X448 self, char * type)
218             CODE:
219             {
220             int rv;
221             unsigned char out[56];
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 = x448_export(out, &out_len, PK_PRIVATE, &self->key);
227 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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 = x448_export(out, &out_len, PK_PUBLIC, &self->key);
232 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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             shared_secret(Crypt::PK::X448 self, Crypt::PK::X448 pubkey)
245             CODE:
246             {
247             int rv;
248             unsigned char buffer[1024];
249 1           unsigned long int buffer_len = sizeof(buffer);
250              
251 1           rv = x448_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
252 1 50         if (rv != CRYPT_OK) croak("FATAL: x448_shared_secret failed: %s", error_to_string(rv));
253 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
254 0           zeromem(buffer, sizeof(buffer));
255             }
256             OUTPUT:
257             RETVAL
258              
259             void
260             DESTROY(Crypt::PK::X448 self)
261             CODE:
262 3 50         if (self->pindex >= 0 && prng_is_valid(self->pindex) == CRYPT_OK && prng_descriptor[self->pindex].done) {
    50          
    50          
263 3           prng_descriptor[self->pindex].done(&self->pstate);
264             }
265 3           zeromem(self, sizeof(*self));
266 3           Safefree(self);