File Coverage

inc/CryptX_PK_X25519.xs.inc
Criterion Covered Total %
statement 28 114 24.5
branch 9 72 12.5
condition n/a
subroutine n/a
pod n/a
total 37 186 19.8


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