File Coverage

inc/CryptX_PK_X448.xs.inc
Criterion Covered Total %
statement 45 125 36.0
branch 17 78 21.7
condition n/a
subroutine n/a
pod n/a
total 62 203 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) {
101 0           pka_key_free(&key_from_pem);
102 0           croak("FATAL: pem_decode_pkcs decoded non-X448 key");
103             }
104 0           self->key = key_from_pem.u.x448;
105 0           self->initialized = 1;
106 0 0         XPUSHs(ST(0)); /* return self */
107             }
108              
109             void
110             _import_x509(Crypt::PK::X448 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 = x448_import_x509(data, (unsigned long)data_len, &self->key);
120 0 0         if (rv != CRYPT_OK) croak("FATAL: x448_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::X448 self, SV * key, int which)
127             PPCODE:
128             {
129             int rv;
130 1           unsigned char *key_data=NULL;
131 1           STRLEN key_len=0;
132              
133 1 50         if (SvOK(key)) {
134 1           key_data = (unsigned char *)SvPVbyte(key, key_len);
135             }
136 1           self->initialized = 0;
137 1 50         if (which == 0) {
138 1           rv = x448_import_raw(key_data, (unsigned long)key_len, PK_PUBLIC, &self->key);
139             }
140 0 0         else if (which == 1) {
141 0           rv = x448_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 1 50         if (rv != CRYPT_OK) croak("FATAL: x448_import_raw failed: %s", error_to_string(rv));
147 1           self->initialized = 1;
148 1 50         XPUSHs(ST(0)); /* return self */
149             }
150              
151             int
152             is_private(Crypt::PK::X448 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::X448 self)
161             PREINIT:
162             HV *rv_hash;
163             char buf[56 * 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, 56, 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, 56, 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("x448", 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::X448 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 = x448_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
204 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: x448_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 = x448_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
209 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: x448_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::X448 self, char * type)
222             CODE:
223             {
224             int rv;
225             unsigned char out[56];
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 = x448_export(out, &out_len, PK_PRIVATE, &self->key);
231 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: x448_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 = x448_export(out, &out_len, PK_PUBLIC, &self->key);
236 0 0         if (rv != CRYPT_OK) { zeromem(out, sizeof(out)); croak("FATAL: x448_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             shared_secret(Crypt::PK::X448 self, Crypt::PK::X448 pubkey)
249             CODE:
250             {
251             int rv;
252             unsigned char buffer[1024];
253 1           unsigned long int buffer_len = sizeof(buffer);
254              
255 1           rv = x448_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
256 1 50         if (rv != CRYPT_OK) { zeromem(buffer, sizeof(buffer)); croak("FATAL: x448_shared_secret failed: %s", error_to_string(rv)); }
257 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
258 0           zeromem(buffer, sizeof(buffer));
259             }
260             OUTPUT:
261             RETVAL
262              
263             void
264             DESTROY(Crypt::PK::X448 self)
265             CODE:
266 3 50         if (self->pindex >= 0 && prng_is_valid(self->pindex) == CRYPT_OK && prng_descriptor[self->pindex].done) {
    50          
    50          
267 3           prng_descriptor[self->pindex].done(&self->pstate);
268             }
269 3           zeromem(self, sizeof(*self));
270 3           Safefree(self);