File Coverage

inc/CryptX_PK_X25519.xs.inc
Criterion Covered Total %
statement 0 112 0.0
branch 0 72 0.0
condition n/a
subroutine n/a
pod n/a
total 0 184 0.0


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::PK::X25519
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::PK::X25519
6             _new(Class)
7             CODE:
8             {
9             int rv;
10 0           Newz(0, RETVAL, 1, struct x25519_struct);
11 0 0         if (!RETVAL) croak("FATAL: Newz failed");
12 0           RETVAL->initialized = 0;
13 0           RETVAL->pindex = find_prng("chacha20");
14 0 0         if (RETVAL->pindex == -1) {
15 0           Safefree(RETVAL);
16 0           croak("FATAL: find_prng('chacha20') failed");
17             }
18 0           rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
19 0 0         if (rv != CRYPT_OK) {
20 0           Safefree(RETVAL);
21 0           croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
22             }
23             }
24             OUTPUT:
25             RETVAL
26              
27             void
28             generate_key(Crypt::PK::X25519 self)
29             PPCODE:
30             {
31             int rv;
32 0           self->initialized = 0;
33 0           rv = x25519_make_key(&self->pstate, self->pindex, &self->key);
34 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_make_key failed: %s", error_to_string(rv));
35 0           self->initialized = 1;
36 0 0         XPUSHs(ST(0)); /* return self */
37             }
38              
39             void
40             _import(Crypt::PK::X25519 self, SV * key_data)
41             PPCODE:
42             {
43             int rv;
44 0           unsigned char *data=NULL;
45 0           STRLEN data_len=0;
46              
47 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
48 0           self->initialized = 0;
49 0           rv = x25519_import(data, (unsigned long)data_len, &self->key);
50 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_import failed: %s", error_to_string(rv));
51 0           self->initialized = 1;
52 0 0         XPUSHs(ST(0)); /* return self */
53             }
54              
55             void
56             _import_pkcs8(Crypt::PK::X25519 self, SV * key_data, SV * passwd)
57             PPCODE:
58             {
59             int rv;
60 0           unsigned char *data = NULL;
61 0           STRLEN data_len = 0;
62 0           password_ctx pw_ctx = { cryptx_internal_password_cb_getpw, cryptx_internal_password_cb_free, passwd };
63              
64 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
65 0           self->initialized = 0;
66 0 0         if (SvOK(passwd)) {
67 0           rv = x25519_import_pkcs8(data, (unsigned long)data_len, &pw_ctx, &self->key);
68             }
69             else {
70 0           rv = x25519_import_pkcs8(data, (unsigned long)data_len, NULL, &self->key);
71             }
72 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_import_pkcs8 failed: %s", error_to_string(rv));
73 0           self->initialized = 1;
74 0 0         XPUSHs(ST(0)); /* return self */
75             }
76              
77             void
78             _import_pem(Crypt::PK::X25519 self, SV * key_data, SV * passwd)
79             PPCODE:
80             {
81             int rv;
82 0           unsigned char *data = NULL;
83 0           STRLEN data_len = 0;
84 0           password_ctx pw_ctx = { cryptx_internal_password_cb_getpw, cryptx_internal_password_cb_free, passwd };
85             ltc_pka_key key_from_pem;
86              
87 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
88 0           self->initialized = 0;
89 0 0         if (SvOK(passwd)) {
90 0           rv = pem_decode_pkcs(data, (unsigned long)data_len, &key_from_pem, &pw_ctx);
91             }
92             else {
93 0           rv = pem_decode_pkcs(data, (unsigned long)data_len, &key_from_pem, NULL);
94             }
95 0 0         if (rv != CRYPT_OK) croak("FATAL: pem_decode_pkcs failed: %s", error_to_string(rv));
96 0 0         if (key_from_pem.id != LTC_PKA_X25519) croak("FATAL: pem_decode_pkcs decoded non-X25519 key");
97 0           self->key = key_from_pem.u.x25519;
98 0           self->initialized = 1;
99 0 0         XPUSHs(ST(0)); /* return self */
100             }
101              
102             void
103             _import_x509(Crypt::PK::X25519 self, SV * key_data)
104             PPCODE:
105             {
106             int rv;
107 0           unsigned char *data=NULL;
108 0           STRLEN data_len=0;
109              
110 0           data = (unsigned char *)SvPVbyte(key_data, data_len);
111 0           self->initialized = 0;
112 0           rv = x25519_import_x509(data, (unsigned long)data_len, &self->key);
113 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_import_x509 failed: %s", error_to_string(rv));
114 0           self->initialized = 1;
115 0 0         XPUSHs(ST(0)); /* return self */
116             }
117              
118             void
119             _import_raw(Crypt::PK::X25519 self, SV * key, int which)
120             PPCODE:
121             {
122             int rv;
123 0           unsigned char *key_data=NULL;
124 0           STRLEN key_len=0;
125              
126 0 0         if (SvOK(key)) {
127 0           key_data = (unsigned char *)SvPVbyte(key, key_len);
128             }
129 0           self->initialized = 0;
130 0 0         if (which == 0) {
131 0           rv = x25519_import_raw(key_data, (unsigned long)key_len, PK_PUBLIC, &self->key);
132             }
133 0 0         else if (which == 1) {
134 0           rv = x25519_import_raw(key_data, (unsigned long)key_len, PK_PRIVATE, &self->key);
135             }
136             else {
137 0           croak("FATAL: import_raw invalid type '%d'", which);
138             }
139 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_import_raw failed: %s", error_to_string(rv));
140 0           self->initialized = 1;
141 0 0         XPUSHs(ST(0)); /* return self */
142             }
143              
144             int
145             is_private(Crypt::PK::X25519 self)
146             CODE:
147 0 0         if (self->initialized == 0) XSRETURN_UNDEF;
148 0 0         RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
149             OUTPUT:
150             RETVAL
151              
152             SV*
153             key2hash(Crypt::PK::X25519 self)
154             PREINIT:
155             HV *rv_hash;
156             char buf[32 * 2 + 1];
157             unsigned long blen;
158             SV **not_used;
159             int rv;
160             CODE:
161 0 0         if (self->initialized == 0) XSRETURN_UNDEF;
162 0           rv_hash = newHV();
163             /* priv */
164 0 0         if (self->key.type == PK_PRIVATE) {
165 0           blen = sizeof(buf);
166 0           rv = base16_encode(self->key.priv, sizeof(self->key.priv), buf, &blen, 0);
167 0 0         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
168 0           not_used = hv_store(rv_hash, "priv", 4, newSVpv(buf, blen), 0);
169             }
170             else {
171 0           not_used = hv_store(rv_hash, "priv", 4, newSVpvn(NULL, 0), 0); /* undef */
172             }
173             /* pub */
174 0           blen = sizeof(buf);
175 0           rv = base16_encode(self->key.pub, sizeof(self->key.pub), buf, &blen, 0);
176 0 0         if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
177 0           not_used = hv_store(rv_hash, "pub", 3, newSVpv(buf, blen), 0);
178             /* curve */
179 0           not_used = hv_store(rv_hash, "curve", 5, newSVpv("x25519", 0), 0);
180             LTC_UNUSED_PARAM(not_used);
181 0           RETVAL = newRV_noinc((SV*)rv_hash);
182             OUTPUT:
183             RETVAL
184              
185             SV*
186             export_key_der(Crypt::PK::X25519 self, char * type)
187             CODE:
188             {
189             int rv;
190             unsigned char out[4096];
191 0           unsigned long int out_len = sizeof(out);
192              
193 0           RETVAL = newSVpvn(NULL, 0); /* undef */
194 0 0         if (strnEQ(type, "private", 7)) {
195 0           rv = x25519_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
196 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE|PK_STD) failed: %s", error_to_string(rv));
197 0           RETVAL = newSVpvn((char*)out, out_len);
198             }
199 0 0         else if (strnEQ(type, "public", 6)) {
200 0           rv = x25519_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
201 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv));
202 0           RETVAL = newSVpvn((char*)out, out_len);
203             }
204             else {
205 0           croak("FATAL: export_key_der invalid type '%s'", type);
206             }
207             }
208             OUTPUT:
209             RETVAL
210              
211             SV*
212             export_key_raw(Crypt::PK::X25519 self, char * type)
213             CODE:
214             {
215             int rv;
216             unsigned char out[32];
217 0           unsigned long int out_len = sizeof(out);
218              
219 0           RETVAL = newSVpvn(NULL, 0); /* undef */
220 0 0         if (strnEQ(type, "private", 7)) {
221 0           rv = x25519_export(out, &out_len, PK_PRIVATE, &self->key);
222 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE) failed: %s", error_to_string(rv));
223 0           RETVAL = newSVpvn((char*)out, out_len);
224             }
225 0 0         else if (strnEQ(type, "public", 6)) {
226 0           rv = x25519_export(out, &out_len, PK_PUBLIC, &self->key);
227 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PUBLIC) failed: %s", error_to_string(rv));
228 0           RETVAL = newSVpvn((char*)out, out_len);
229             }
230             else {
231 0           croak("FATAL: export_key_raw invalid type '%s'", type);
232             }
233             }
234             OUTPUT:
235             RETVAL
236              
237             SV *
238             shared_secret(Crypt::PK::X25519 self, Crypt::PK::X25519 pubkey)
239             CODE:
240             {
241             int rv;
242             unsigned char buffer[1024];
243 0           unsigned long int buffer_len = sizeof(buffer);
244              
245 0           rv = x25519_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
246 0 0         if (rv != CRYPT_OK) croak("FATAL: x25519_shared_secret failed: %s", error_to_string(rv));
247 0           RETVAL = newSVpvn((char*)buffer, buffer_len);
248             }
249             OUTPUT:
250             RETVAL
251              
252             void
253             DESTROY(Crypt::PK::X25519 self)
254             CODE:
255 0           Safefree(self);