File Coverage

CryptX.xs
Criterion Covered Total %
statement 616 733 84.0
branch 460 778 59.1
condition n/a
subroutine n/a
pod n/a
total 1076 1511 71.2


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT /* we want efficiency */
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #define NEED_sv_2pvbyte_GLOBAL
7             #define NEED_sv_2pv_flags_GLOBAL
8             #define NEED_newRV_noinc_GLOBAL
9             #include "ppport.h"
10              
11             /* assert_not_ROK is broken in 5.8.1 */
12             #if PERL_VERSION == 8 && PERL_SUBVERSION == 1
13             # undef assert_not_ROK
14             # if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
15             # define assert_not_ROK(sv) ({assert(!SvROK(sv) || !SvRV(sv));}),
16             # else
17             # define assert_not_ROK(sv)
18             # endif
19             #endif
20              
21             /* HACK: https://github.com/DCIT/perl-CryptX/issues/105 (replacement for SvPOK(sv) suggestet by Leont) */
22             #define SvPOK_spec(sv) (SvOK(sv) && (!SvROK(sv) || SvAMAGIC(sv)))
23              
24             #undef LTC_SOURCE
25             #include "tomcrypt.h"
26             #include "tommath.h"
27              
28 655           STATIC int cryptx_internal_input_has_no_payload(const char *in, STRLEN len) {
29             STRLEN i;
30 655           int saw_formatting = 0;
31              
32 655 50         if (in == NULL || len == 0) return 0;
    50          
33              
34 684 100         for (i = 0; i < len; i++) {
35 675 100         if (in[i] == '=') {
36 10           saw_formatting = 1;
37 10           continue;
38             }
39 665 100         if (in[i] == ' ' || in[i] == '\t' || in[i] == '\n' || in[i] == '\r') {
    100          
    100          
    50          
40 19           saw_formatting = 1;
41 19           continue;
42             }
43 646           return 0;
44             }
45 9           return saw_formatting;
46             }
47              
48             typedef adler32_state *Crypt__Checksum__Adler32;
49             typedef crc32_state *Crypt__Checksum__CRC32;
50              
51             typedef struct cryptx_authenc_ccm_struct {
52             ccm_state state;
53             int finalized;
54             } *Crypt__AuthEnc__CCM;
55             typedef struct cryptx_authenc_eax_struct {
56             eax_state state;
57             int finalized;
58             } *Crypt__AuthEnc__EAX;
59             typedef struct cryptx_authenc_gcm_struct {
60             gcm_state state;
61             int finalized;
62             } *Crypt__AuthEnc__GCM;
63             typedef struct cryptx_authenc_chacha20poly1305_struct {
64             chacha20poly1305_state state;
65             int finalized;
66             } *Crypt__AuthEnc__ChaCha20Poly1305;
67             typedef struct cryptx_authenc_ocb_struct {
68             ocb3_state state;
69             int finalized;
70             } *Crypt__AuthEnc__OCB;
71              
72             typedef chacha_state *Crypt__Stream__ChaCha;
73             typedef chacha_state *Crypt__Stream__XChaCha;
74             typedef salsa20_state *Crypt__Stream__Salsa20;
75             typedef salsa20_state *Crypt__Stream__XSalsa20;
76             typedef sosemanuk_state *Crypt__Stream__Sosemanuk;
77             typedef rabbit_state *Crypt__Stream__Rabbit;
78             typedef rc4_state *Crypt__Stream__RC4;
79             typedef sober128_state *Crypt__Stream__Sober128;
80              
81             typedef struct cryptx_mac_f9_struct {
82             f9_state state;
83             int finalized;
84             } *Crypt__Mac__F9;
85             typedef struct cryptx_mac_hmac_struct {
86             hmac_state state;
87             int finalized;
88             } *Crypt__Mac__HMAC;
89             typedef struct cryptx_mac_omac_struct {
90             omac_state state;
91             int finalized;
92             } *Crypt__Mac__OMAC;
93             typedef struct cryptx_mac_pelican_struct {
94             pelican_state state;
95             int finalized;
96             } *Crypt__Mac__Pelican;
97             typedef struct cryptx_mac_pmac_struct {
98             pmac_state state;
99             int finalized;
100             } *Crypt__Mac__PMAC;
101             typedef struct cryptx_mac_xcbc_struct {
102             xcbc_state state;
103             int finalized;
104             } *Crypt__Mac__XCBC;
105             typedef struct cryptx_mac_poly1305_struct {
106             poly1305_state state;
107             int finalized;
108             } *Crypt__Mac__Poly1305;
109             typedef struct cryptx_mac_blake2s_struct {
110             blake2smac_state state;
111             int finalized;
112             } *Crypt__Mac__BLAKE2s;
113             typedef struct cryptx_mac_blake2b_struct {
114             blake2bmac_state state;
115             int finalized;
116             } *Crypt__Mac__BLAKE2b;
117             typedef struct cryptx_mac_kmac_struct {
118             kmac_state state;
119             int finalized;
120             int variant;
121             } *Crypt__Mac__KMAC;
122              
123             typedef struct cipher_struct { /* used by Crypt::Cipher */
124             symmetric_key skey;
125             struct ltc_cipher_descriptor *desc;
126             } *Crypt__Cipher;
127              
128             typedef struct digest_struct { /* used by Crypt::Digest */
129             hash_state state;
130             struct ltc_hash_descriptor *desc;
131             int finalized;
132             } *Crypt__Digest;
133              
134 93           STATIC int cryptx_internal_noclone_hash(const char *name) {
135 93 50         if (name == NULL) return 0;
136 93           return strcmp(name, "sha1") == 0
137 93 50         || strcmp(name, "sha224") == 0
138 186 50         || strcmp(name, "sha256") == 0;
    50          
139             }
140              
141             typedef struct digest_shake_struct { /* used by Crypt::Digest::SHAKE, TurboSHAKE, KangarooTwelve */
142             hash_state state;
143             int num;
144             int squeezing;
145             } *Crypt__Digest__SHAKE;
146             typedef struct digest_shake_struct *Crypt__Digest__TurboSHAKE;
147             typedef struct digest_shake_struct *Crypt__Digest__KangarooTwelve;
148              
149             /* --- Crypt::ASN1 helper -------------------------------------------------- */
150             static const char * const s_asn1_class_names[] = {
151             "UNIVERSAL", "APPLICATION", "CONTEXT_SPECIFIC", "PRIVATE"
152             };
153              
154             typedef struct { int int_fmt; int bin_fmt; int dt_fmt; HV *oidmap; } asn1_opts_t;
155             /* int_fmt: 0=decimal(default) 1=hex 2=bytes */
156             /* bin_fmt: 0=raw(default) 1=hex 2=base64 */
157             /* dt_fmt: 0=rfc3339(default) 1=epoch */
158              
159 56           static SV * s_asn1_oid_name_sv(pTHX_ HV *oidmap, SV *oid_sv)
160             {
161 56           STRLEN len = 0;
162 56           const char *oid = NULL;
163 56           SV **name_sv = NULL;
164              
165 56 100         if (!oidmap || !oid_sv || !SvOK(oid_sv)) return NULL;
    50          
    50          
166              
167 1           oid = SvPV(oid_sv, len);
168 1           name_sv = hv_fetch(oidmap, oid, (I32)len, 0);
169 1 50         if (!name_sv || !SvOK(*name_sv)) return NULL;
    50          
170              
171 1           return newSVsv(*name_sv);
172             }
173              
174             /* Encode binary data according to bin_fmt */
175 56           static SV * s_asn1_bin_sv(pTHX_ const void *data, unsigned long size, int bin_fmt)
176             {
177 56 50         if (!data || size == 0) return newSVpvn("", 0);
    50          
178 56 100         if (bin_fmt == 1) { /* hex */
179             SV *s;
180 6           unsigned long outlen = size * 2 + 1;
181 6           char *buf; Newz(0, buf, outlen, char);
182 6           { unsigned long ol = outlen; base16_encode((const unsigned char*)data, size, buf, &ol, 0); }
183 6           s = newSVpvn(buf, size * 2); Safefree(buf);
184 6           return s;
185 50 100         } else if (bin_fmt == 2) { /* base64 */
186             SV *s;
187 11           unsigned long outlen = ((size + 2) / 3) * 4 + 4;
188 11           char *buf; Newz(0, buf, outlen, char);
189 11           base64_encode((const unsigned char*)data, size, buf, &outlen);
190 11           s = newSVpvn(buf, outlen); Safefree(buf);
191 11           return s;
192             }
193 39           return newSVpvn((const char *)data, size); /* raw */
194             }
195              
196             /* Convert Gregorian date+time to Unix epoch (portable, no timegm needed) */
197 7           static IV s_asn1_to_epoch(unsigned YYYY, unsigned MM, unsigned DD,
198             unsigned hh, unsigned mm, unsigned ss,
199             unsigned off_dir, unsigned off_hh, unsigned off_mm)
200             {
201 7           long y = YYYY, m = MM, d = DD;
202             long days;
203             IV epoch, offset;
204 7 100         if (m <= 2) { y--; m += 12; }
205 7           days = 365*y + y/4 - y/100 + y/400 + (153*m - 457)/5 + d - 719469;
206 7           epoch = (IV)days * 86400 + (IV)hh * 3600 + (IV)mm * 60 + (IV)ss;
207 7           offset = (IV)(off_hh * 3600 + off_mm * 60);
208             /* off_dir: 0 = '+' (local ahead of UTC, subtract to get UTC)
209             * 1 = '-' (local behind UTC, add to get UTC) */
210 7 50         epoch += (off_dir ? offset : -offset);
211 7           return epoch;
212             }
213              
214 190           static SV * s_ltc_asn1_to_perl(pTHX_ ltc_asn1_list *node, asn1_opts_t opts)
215             {
216 190           AV *av = newAV();
217 556 100         while (node != NULL && node->type != LTC_ASN1_EOL) {
    100          
218 367           HV *hv = newHV();
219 367           SV *value_sv = NULL;
220 367           const char *type_str = "UNKNOWN";
221 367           const char *format_str = "unknown";
222 367           switch (node->type) {
223 3           case LTC_ASN1_BOOLEAN:
224 3           type_str = "BOOLEAN"; format_str = "bool";
225 3 50         if (node->data) value_sv = newSViv(*(int *)node->data ? 1 : 0);
226 3           break;
227 44           case LTC_ASN1_INTEGER: {
228 44           mp_int *mpi = (mp_int *)node->data;
229 44           type_str = "INTEGER";
230 44 50         if (mpi) {
231 44 100         if (opts.int_fmt == 2) { /* bytes */
232 5 100         if (mp_isneg(mpi)) {
233 1           SvREFCNT_dec(hv);
234 1           croak("FATAL: asn1_decode_der: negative INTEGER cannot be represented with int=>'bytes'");
235             }
236 4           format_str = "bytes";
237 4 100         if (mp_iszero(mpi)) {
238 1           value_sv = newSVpvn("\0", 1);
239             } else {
240 3           unsigned long usize = mp_ubin_size(mpi);
241 3           unsigned char *ubuf; Newz(0, ubuf, usize, unsigned char);
242 3           { mp_err me = mp_to_ubin(mpi, ubuf, usize, NULL); PERL_UNUSED_VAR(me); }
243 3           value_sv = newSVpvn((char *)ubuf, usize); Safefree(ubuf);
244             }
245             } else {
246 39 100         int radix = (opts.int_fmt == 1) ? 16 : 10;
247             int len;
248             char *buf;
249 39 100         format_str = (opts.int_fmt == 1) ? "hex" : "decimal";
250 39 100         len = mp_count_bits(mpi) / (opts.int_fmt == 1 ? 4 : 3) + 4;
251 39           Newz(0, buf, len, char);
252 39           { mp_err me = mp_to_radix(mpi, buf, len, NULL, radix); PERL_UNUSED_VAR(me); }
253 39 100         if (opts.int_fmt == 1) { /* lowercase hex */
254 41 100         char *p; for (p = buf; *p; p++) if (*p >= 'A' && *p <= 'F') *p += 32;
    50          
    100          
255             }
256 39           value_sv = newSVpv(buf, 0); Safefree(buf);
257             }
258             }
259 43           break;
260             }
261 0           case LTC_ASN1_SHORT_INTEGER: {
262 0           type_str = "INTEGER";
263 0 0         if (node->data) {
264 0           unsigned long v = *(unsigned long *)node->data;
265 0 0         if (opts.int_fmt == 1) { /* hex */
266             char buf[32];
267 0           format_str = "hex";
268 0           snprintf(buf, sizeof(buf), "%lx", v);
269 0           value_sv = newSVpv(buf, 0);
270 0 0         } else if (opts.int_fmt == 2) { /* bytes */
271             unsigned char b[8], be[8];
272 0           int n = 0, k;
273 0           unsigned long tmp = v;
274 0           format_str = "bytes";
275 0 0         while (tmp) { b[n++] = (unsigned char)(tmp & 0xff); tmp >>= 8; }
276 0 0         if (!n) { b[0] = 0; n = 1; }
277 0 0         for (k = 0; k < n; k++) be[k] = b[n - 1 - k];
278 0           value_sv = newSVpvn((char *)be, n);
279             } else {
280 0           format_str = "decimal";
281 0           value_sv = newSVuv((UV)v);
282             }
283             }
284 0           break;
285             }
286 18           case LTC_ASN1_BIT_STRING: {
287 18           unsigned char *bits = (unsigned char *)node->data;
288 18           unsigned long nbits = node->size, nbytes = (nbits + 7) / 8;
289 18           type_str = "BIT_STRING";
290 18 100         format_str = (opts.bin_fmt == 1) ? "hex" : (opts.bin_fmt == 2) ? "base64" : "bytes";
    100          
291 18 50         if (bits && nbytes > 0) {
    50          
292             unsigned long i;
293             unsigned char *packed;
294 18           Newz(0, packed, nbytes, unsigned char);
295 28074 100         for (i = 0; i < nbits; i++)
296 28056 100         if (bits[i]) packed[i/8] |= (unsigned char)(0x80u >> (i%8));
297 18           value_sv = s_asn1_bin_sv(aTHX_ packed, nbytes, opts.bin_fmt);
298 18           Safefree(packed);
299             }
300 18           hv_stores(hv, "bits", newSVuv((UV)nbits));
301 18           break;
302             }
303 0           case LTC_ASN1_RAW_BIT_STRING: {
304 0           unsigned long nbits_raw = node->size;
305 0           unsigned long nbytes_raw = (nbits_raw + 7) / 8;
306 0           type_str = "BIT_STRING";
307 0 0         format_str = (opts.bin_fmt == 1) ? "hex" : (opts.bin_fmt == 2) ? "base64" : "bytes";
    0          
308 0           value_sv = s_asn1_bin_sv(aTHX_ node->data, nbytes_raw, opts.bin_fmt);
309 0           hv_stores(hv, "bits", newSVuv((UV)nbits_raw));
310 0           break;
311             }
312 37           case LTC_ASN1_OCTET_STRING:
313 37           type_str = "OCTET_STRING";
314 37 100         format_str = (opts.bin_fmt == 1) ? "hex" : (opts.bin_fmt == 2) ? "base64" : "bytes";
    100          
315 37           value_sv = s_asn1_bin_sv(aTHX_ node->data, node->size, opts.bin_fmt);
316 37           break;
317 20           case LTC_ASN1_NULL:
318 20           type_str = "NULL"; format_str = "null";
319 20           break;
320 56           case LTC_ASN1_OBJECT_IDENTIFIER: {
321 56           unsigned long *oid = (unsigned long *)node->data;
322 56           type_str = "OID"; format_str = "oid";
323 56 50         if (oid && node->size > 0) {
    50          
324 56           unsigned long i; SV *s = newSVpvn("", 0);
325 337 100         for (i = 0; i < node->size; i++) {
326 281 100         if (i > 0) sv_catpv(s, "."); sv_catpvf(s, "%lu", oid[i]);
327             }
328 56           value_sv = s;
329             {
330 56           SV *name_sv = s_asn1_oid_name_sv(aTHX_ opts.oidmap, value_sv);
331 56 100         if (name_sv) hv_stores(hv, "name", name_sv);
332             }
333             }
334 56           break;
335             }
336 2           case LTC_ASN1_IA5_STRING:
337 2           type_str = "IA5_STRING"; format_str = "string";
338 2 50         if (node->data && node->size > 0) value_sv = newSVpvn((char *)node->data, node->size);
    50          
339 2           break;
340 2           case LTC_ASN1_PRINTABLE_STRING:
341 2           type_str = "PRINTABLE_STRING"; format_str = "string";
342 2 50         if (node->data && node->size > 0) value_sv = newSVpvn((char *)node->data, node->size);
    50          
343 2           break;
344 0           case LTC_ASN1_TELETEX_STRING:
345 0           type_str = "TELETEX_STRING"; format_str = "string";
346 0 0         if (node->data && node->size > 0) value_sv = newSVpvn((char *)node->data, node->size);
    0          
347 0           break;
348 14           case LTC_ASN1_UTF8_STRING: {
349 14           wchar_t *wstr = (wchar_t *)node->data;
350 14           type_str = "UTF8_STRING"; format_str = "utf8";
351 14 50         if (wstr && node->size > 0) {
    50          
352             unsigned long i;
353 14           SV *s = newSVpvn("", 0); SvUTF8_on(s);
354 78 100         for (i = 0; i < node->size; i++) {
355             U8 ubuf[UTF8_MAXBYTES + 1];
356 64           U8 *end = uvchr_to_utf8(ubuf, (UV)wstr[i]);
357 64           sv_catpvn(s, (char *)ubuf, end - ubuf);
358             }
359 14           value_sv = s;
360             }
361 14           break;
362             }
363 16           case LTC_ASN1_UTCTIME: {
364 16           ltc_utctime *t = (ltc_utctime *)node->data;
365 16           type_str = "UTCTIME";
366 16 50         if (t) {
367 16 50         unsigned YYYY = (t->YY >= 50) ? 1900 + t->YY : 2000 + t->YY;
368 16 100         if (opts.dt_fmt == 1) { /* epoch */
369 6           format_str = "epoch";
370 6           value_sv = newSViv(s_asn1_to_epoch(YYYY, t->MM, t->DD, t->hh, t->mm, t->ss,
371             t->off_dir, t->off_hh, t->off_mm));
372             } else { /* rfc3339 */
373             char buf[32];
374 10           format_str = "rfc3339";
375 10 50         if (t->off_dir == 0 && t->off_hh == 0 && t->off_mm == 0)
    50          
    50          
376 10           snprintf(buf, sizeof(buf), "%04u-%02u-%02uT%02u:%02u:%02uZ",
377             YYYY, t->MM, t->DD, t->hh, t->mm, t->ss);
378             else
379 0           snprintf(buf, sizeof(buf), "%04u-%02u-%02uT%02u:%02u:%02u%c%02u:%02u",
380             YYYY, t->MM, t->DD, t->hh, t->mm, t->ss,
381 0 0         t->off_dir ? '-' : '+', t->off_hh, t->off_mm);
382 10           value_sv = newSVpv(buf, 0);
383             }
384             }
385 16           break;
386             }
387 5           case LTC_ASN1_GENERALIZEDTIME: {
388 5           ltc_generalizedtime *t = (ltc_generalizedtime *)node->data;
389 5           type_str = "GENERALIZEDTIME";
390 5 50         if (t) {
391 5 100         if (opts.dt_fmt == 1) { /* epoch */
392 1           format_str = "epoch";
393 1           value_sv = newSViv(s_asn1_to_epoch(t->YYYY, t->MM, t->DD, t->hh, t->mm, t->ss,
394             t->off_dir, t->off_hh, t->off_mm));
395             } else { /* rfc3339 */
396             char buf[48];
397             int pos;
398 4           format_str = "rfc3339";
399 4           pos = snprintf(buf, sizeof(buf), "%04u-%02u-%02uT%02u:%02u:%02u",
400             t->YYYY, t->MM, t->DD, t->hh, t->mm, t->ss);
401 4 100         if (t->fs > 0)
402 3           pos += snprintf(buf + pos, sizeof(buf) - pos, ".%u", t->fs);
403 4 50         if (t->off_dir == 0 && t->off_hh == 0 && t->off_mm == 0)
    100          
    50          
404 3           snprintf(buf + pos, sizeof(buf) - pos, "Z");
405             else
406 1           snprintf(buf + pos, sizeof(buf) - pos, "%c%02u:%02u",
407 1 50         t->off_dir ? '-' : '+', t->off_hh, t->off_mm);
408 4           value_sv = newSVpv(buf, 0);
409             }
410             }
411 5           break;
412             }
413 115           case LTC_ASN1_SEQUENCE:
414 115           type_str = "SEQUENCE"; format_str = "array";
415 115 50         value_sv = node->child ? newRV_noinc(s_ltc_asn1_to_perl(aTHX_ node->child, opts)) : newRV_noinc((SV *)newAV());
416 115           break;
417 14           case LTC_ASN1_SET:
418             case LTC_ASN1_SETOF:
419 14           type_str = "SET"; format_str = "array";
420 14 50         value_sv = node->child ? newRV_noinc(s_ltc_asn1_to_perl(aTHX_ node->child, opts)) : newRV_noinc((SV *)newAV());
421 14           break;
422 21           case LTC_ASN1_CUSTOM_TYPE: {
423 21           unsigned int cls = (unsigned int)node->klass;
424 21           type_str = "CUSTOM";
425 21 50         hv_stores(hv, "class", newSVpv((cls < 4) ? s_asn1_class_names[cls] : "UNKNOWN", 0));
426 21           hv_stores(hv, "constructed", newSViv(node->pc == LTC_ASN1_PC_CONSTRUCTED ? 1 : 0));
427 21           hv_stores(hv, "tag", newSVuv((UV)node->tag));
428 21 100         if (node->pc == LTC_ASN1_PC_CONSTRUCTED && node->child) {
    50          
429 20           format_str = "array";
430 20           value_sv = newRV_noinc(s_ltc_asn1_to_perl(aTHX_ node->child, opts));
431 1 50         } else if (node->data && node->size > 0) {
    50          
432 1 50         format_str = (opts.bin_fmt == 1) ? "hex" : (opts.bin_fmt == 2) ? "base64" : "bytes";
    50          
433 1           value_sv = s_asn1_bin_sv(aTHX_ node->data, node->size, opts.bin_fmt);
434             }
435 21           break;
436             }
437 0           default:
438             /* Unknown ltc_asn1_type — skip rather than emit unroundtrippable node */
439 0           SvREFCNT_dec(hv);
440 0           node = node->next;
441 0           continue;
442             }
443 366           hv_stores(hv, "type", newSVpv(type_str, 0));
444 366           hv_stores(hv, "format", newSVpv(format_str, 0));
445 366 100         hv_stores(hv, "value", value_sv ? value_sv : newSV(0));
446 366           av_push(av, newRV_noinc((SV *)hv));
447 366           node = node->next;
448             }
449 189           return (SV *)av;
450             }
451             /* --- end Crypt::ASN1 decoder helper -------------------------------------- */
452              
453             /* --- Crypt::ASN1 encoder helpers ----------------------------------------- */
454              
455             /* Write DER length to buf, return bytes written (buf must be >= 5 bytes) */
456 141           static unsigned long s_asn1_put_der_length(pTHX_ unsigned char *buf, unsigned long len)
457             {
458 141 50         if (len > 0xffffffffUL) {
459 0           croak("FATAL: asn1_encode: DER length exceeds 0xffffffff bytes");
460             }
461 141 100         if (len < 128) {
462 123           buf[0] = (unsigned char)len;
463 123           return 1;
464 18 50         } else if (len <= 0xffUL) {
465 0           buf[0] = 0x81; buf[1] = (unsigned char)len;
466 0           return 2;
467 18 50         } else if (len <= 0xffffUL) {
468 18           buf[0] = 0x82;
469 18           buf[1] = (unsigned char)(len >> 8);
470 18           buf[2] = (unsigned char)(len & 0xff);
471 18           return 3;
472 0 0         } else if (len <= 0xffffffUL) {
473 0           buf[0] = 0x83;
474 0           buf[1] = (unsigned char)(len >> 16);
475 0           buf[2] = (unsigned char)((len >> 8) & 0xff);
476 0           buf[3] = (unsigned char)(len & 0xff);
477 0           return 4;
478             }
479 0           buf[0] = 0x84;
480 0           buf[1] = (unsigned char)(len >> 24);
481 0           buf[2] = (unsigned char)((len >> 16) & 0xff);
482 0           buf[3] = (unsigned char)((len >> 8) & 0xff);
483 0           buf[4] = (unsigned char)(len & 0xff);
484 0           return 5;
485             }
486              
487             /* Append single-byte tag + DER length + content to SV */
488 130           static void s_asn1_append_tlv(pTHX_ SV *out, unsigned char tag,
489             const void *content, unsigned long clen)
490             {
491             unsigned char lbuf[5];
492 130           unsigned long llen = s_asn1_put_der_length(aTHX_ lbuf, clen);
493 130           sv_catpvn(out, (char *)&tag, 1);
494 130           sv_catpvn(out, (char *)lbuf, llen);
495 130 100         if (clen > 0 && content) sv_catpvn(out, (const char *)content, clen);
    50          
496 130           }
497              
498             /* Append multi-byte tag (for CUSTOM) + DER length + content to SV */
499 11           static void s_asn1_append_custom_tlv(pTHX_ SV *out,
500             unsigned int klass, unsigned int pc,
501             unsigned long tag,
502             const void *content, unsigned long clen)
503             {
504             unsigned char tbuf[12], lbuf[5];
505             unsigned long tlen, llen;
506 11           unsigned char first = (unsigned char)(((klass & 0x3) << 6) | ((pc & 0x1) << 5));
507              
508 11 50         if (tag < 31) {
509 11           tbuf[0] = first | (unsigned char)tag;
510 11           tlen = 1;
511             } else {
512             unsigned char tmp[10];
513 0           int n = 0, i;
514 0           unsigned long t = tag;
515 0           tbuf[0] = first | 0x1f;
516             /* base-128 big-endian */
517 0 0         do { tmp[n++] = (unsigned char)(t & 0x7f); t >>= 7; } while (t > 0);
518 0           tlen = 1;
519 0 0         for (i = n - 1; i >= 0; i--) tbuf[tlen++] = tmp[i] | (i > 0 ? 0x80 : 0x00);
    0          
520             }
521 11           llen = s_asn1_put_der_length(aTHX_ lbuf, clen);
522 11           sv_catpvn(out, (char *)tbuf, tlen);
523 11           sv_catpvn(out, (char *)lbuf, llen);
524 11 100         if (clen > 0 && content) sv_catpvn(out, (const char *)content, clen);
    50          
525 11           }
526              
527             /* Forward declarations */
528             static void s_asn1_encode_node(pTHX_ SV *out, HV *node);
529              
530 115           static void s_asn1_encode_nodes(pTHX_ SV *out, AV *nodes)
531             {
532 115 50         I32 i, len = av_top_index(nodes);
533 309 100         for (i = 0; i <= len; i++) {
534 194           SV **elem = av_fetch(nodes, i, 0);
535 194 50         if (!elem || !SvROK(*elem) || SvTYPE(SvRV(*elem)) != SVt_PVHV) continue;
    50          
    50          
536 194           s_asn1_encode_node(aTHX_ out, (HV *)SvRV(*elem));
537             }
538 115           }
539              
540 194           static void s_asn1_encode_node(pTHX_ SV *out, HV *node)
541             {
542 194           SV **sv_type = hv_fetchs(node, "type", 0);
543 194           SV **sv_value = hv_fetchs(node, "value", 0);
544             const char *type;
545              
546 194 50         if (!sv_type || !SvOK(*sv_type)) croak("FATAL: asn1_encode: node missing 'type'");
    50          
547 194           type = SvPV_nolen(*sv_type);
548              
549 194 100         if (strEQ(type, "BOOLEAN")) {
550 4 50         int val = (sv_value && SvOK(*sv_value)) ? SvIV(*sv_value) : 0;
    50          
551 4 100         unsigned char c = val ? 0xFF : 0x00;
552 4           s_asn1_append_tlv(aTHX_ out, 0x01, &c, 1);
553             }
554 190 100         else if (strEQ(type, "NULL")) {
555 11           s_asn1_append_tlv(aTHX_ out, 0x05, NULL, 0);
556             }
557 179 100         else if (strEQ(type, "INTEGER")) {
558             STRLEN slen; const char *str;
559             mp_int mpi; int rv;
560             unsigned long outlen; unsigned char *buf;
561              
562 25 50         if (!sv_value || !SvOK(*sv_value)) croak("FATAL: asn1_encode: INTEGER missing value");
    50          
563 25           str = SvPV(*sv_value, slen);
564              
565 25 50         if (mp_init(&mpi) != MP_OKAY) croak("FATAL: asn1_encode: mp_init failed");
566 25 50         if (mp_read_radix(&mpi, str, 10) != MP_OKAY) { mp_clear(&mpi); croak("FATAL: asn1_encode: invalid INTEGER value '%s'", str); }
567              
568 25           rv = der_length_integer(&mpi, &outlen);
569 25 50         if (rv != CRYPT_OK) { mp_clear(&mpi); croak("FATAL: asn1_encode: der_length_integer failed"); }
570              
571 25           Newx(buf, outlen, unsigned char);
572 25           rv = der_encode_integer(&mpi, buf, &outlen);
573 25           mp_clear(&mpi);
574 25 50         if (rv != CRYPT_OK) { Safefree(buf); croak("FATAL: asn1_encode: der_encode_integer failed"); }
575              
576 25           sv_catpvn(out, (char *)buf, outlen);
577 25           Safefree(buf);
578             }
579 154 100         else if (strEQ(type, "OID")) {
580             STRLEN slen; const char *str; const char *p;
581 28           unsigned long words[64], nwords = 0, outlen;
582             unsigned char *buf; int rv;
583              
584 28 50         if (!sv_value || !SvOK(*sv_value)) croak("FATAL: asn1_encode: OID missing value");
    50          
585 28           str = SvPV(*sv_value, slen);
586              
587 28           p = str;
588 166 100         while (*p && nwords < 64) {
    50          
589 138           words[nwords++] = strtoul(p, (char **)&p, 10);
590 138 100         if (*p == '.') p++;
591             }
592 28 50         if (nwords < 2) croak("FATAL: asn1_encode: OID must have at least 2 arcs");
593              
594 28           rv = der_length_object_identifier(words, nwords, &outlen);
595 28 50         if (rv != CRYPT_OK) croak("FATAL: asn1_encode: der_length_object_identifier failed");
596              
597 28           Newx(buf, outlen, unsigned char);
598 28           rv = der_encode_object_identifier(words, nwords, buf, &outlen);
599 28 50         if (rv != CRYPT_OK) { Safefree(buf); croak("FATAL: asn1_encode: der_encode_object_identifier failed"); }
600              
601 28           sv_catpvn(out, (char *)buf, outlen);
602 28           Safefree(buf);
603             }
604 126 100         else if (strEQ(type, "OCTET_STRING")) {
605 17           STRLEN vlen = 0;
606 17 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
607 17           s_asn1_append_tlv(aTHX_ out, 0x04, data, (unsigned long)vlen);
608             }
609 109 100         else if (strEQ(type, "BIT_STRING")) {
610 11           STRLEN vlen = 0;
611 11 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
612 11           SV **sv_bits = hv_fetchs(node, "bits", 0);
613 11 50         unsigned long nbits = (sv_bits && SvOK(*sv_bits)) ? (unsigned long)SvUV(*sv_bits) : (unsigned long)(vlen * 8);
    50          
614 11           unsigned long nbytes = (nbits + 7) / 8;
615 11 50         unsigned char unused = (nbytes > 0) ? (unsigned char)(8 * nbytes - nbits) : 0;
616 11           unsigned long content_len = 1 + nbytes;
617             unsigned char *content;
618              
619 11           Newxz(content, content_len, unsigned char);
620 11           content[0] = unused;
621 11 50         if (nbytes > 0 && vlen > 0) {
    50          
622 11           Copy(data, content + 1, nbytes < (unsigned long)vlen ? nbytes : (unsigned long)vlen, unsigned char);
623 11 100         if (unused > 0) content[nbytes] &= (unsigned char)(0xFF << unused);
624             }
625 11           s_asn1_append_tlv(aTHX_ out, 0x03, content, content_len);
626 11           Safefree(content);
627             }
628 98 100         else if (strEQ(type, "UTF8_STRING")) {
629 8           STRLEN vlen = 0;
630 8 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVutf8(*sv_value, vlen) : "";
    50          
631 8           s_asn1_append_tlv(aTHX_ out, 0x0C, data, (unsigned long)vlen);
632             }
633 90 100         else if (strEQ(type, "IA5_STRING")) {
634 2           STRLEN vlen = 0;
635 2 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
636 2           s_asn1_append_tlv(aTHX_ out, 0x16, data, (unsigned long)vlen);
637             }
638 88 100         else if (strEQ(type, "PRINTABLE_STRING")) {
639 2           STRLEN vlen = 0;
640 2 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
641 2           s_asn1_append_tlv(aTHX_ out, 0x13, data, (unsigned long)vlen);
642             }
643 86 100         else if (strEQ(type, "TELETEX_STRING")) {
644 1           STRLEN vlen = 0;
645 1 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
646 1           s_asn1_append_tlv(aTHX_ out, 0x14, data, (unsigned long)vlen);
647             }
648 85 100         else if (strEQ(type, "UTCTIME")) {
649 10           STRLEN vlen = 0;
650 10 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPV(*sv_value, vlen) : "";
    50          
651 10           s_asn1_append_tlv(aTHX_ out, 0x17, data, (unsigned long)vlen);
652             }
653 75 100         else if (strEQ(type, "GENERALIZEDTIME")) {
654 1           STRLEN vlen = 0;
655 1 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPV(*sv_value, vlen) : "";
    50          
656 1           s_asn1_append_tlv(aTHX_ out, 0x18, data, (unsigned long)vlen);
657             }
658 137 100         else if (strEQ(type, "SEQUENCE") || strEQ(type, "SET")) {
    100          
659 63 100         unsigned char tag = strEQ(type, "SEQUENCE") ? 0x30 : 0x31;
660 126 50         if (sv_value && SvROK(*sv_value) && SvTYPE(SvRV(*sv_value)) == SVt_PVAV) {
    50          
    50          
661 63           SV *content = newSVpvn("", 0);
662 63           s_asn1_encode_nodes(aTHX_ content, (AV *)SvRV(*sv_value));
663 63           { STRLEN clen; const char *cdata = SvPV(content, clen);
664 63           s_asn1_append_tlv(aTHX_ out, tag, cdata, (unsigned long)clen); }
665 63           SvREFCNT_dec(content);
666             } else {
667 0           s_asn1_append_tlv(aTHX_ out, tag, NULL, 0);
668             }
669             }
670 11 50         else if (strEQ(type, "CUSTOM")) {
671 11           SV **sv_class = hv_fetchs(node, "class", 0);
672 11           SV **sv_constr = hv_fetchs(node, "constructed", 0);
673 11           SV **sv_tag = hv_fetchs(node, "tag", 0);
674 11 50         unsigned int klass = (sv_class && SvOK(*sv_class)) ? (unsigned int)SvIV(*sv_class) : 2;
    50          
675 11 50         unsigned int pc = (sv_constr && SvOK(*sv_constr) && SvIV(*sv_constr)) ? 1 : 0;
    50          
    100          
676 11 50         unsigned long tag = (sv_tag && SvOK(*sv_tag)) ? (unsigned long)SvUV(*sv_tag) : 0;
    50          
677              
678 21 100         if (pc && sv_value && SvROK(*sv_value) && SvTYPE(SvRV(*sv_value)) == SVt_PVAV) {
    50          
    50          
    50          
679 10           SV *content = newSVpvn("", 0);
680 10           s_asn1_encode_nodes(aTHX_ content, (AV *)SvRV(*sv_value));
681 10           { STRLEN clen; const char *cdata = SvPV(content, clen);
682 10           s_asn1_append_custom_tlv(aTHX_ out, klass, pc, tag, cdata, (unsigned long)clen); }
683 10           SvREFCNT_dec(content);
684             } else {
685 1           STRLEN vlen = 0;
686 1 50         const char *data = (sv_value && SvOK(*sv_value)) ? SvPVbyte(*sv_value, vlen) : "";
    50          
687 1           s_asn1_append_custom_tlv(aTHX_ out, klass, pc, tag, data, (unsigned long)vlen);
688             }
689             }
690             else {
691 0           croak("FATAL: asn1_encode: unsupported type '%s'", type);
692             }
693 194           }
694             /* --- end Crypt::ASN1 encoder helpers ------------------------------------- */
695              
696             typedef struct cbc_struct { /* used by Crypt::Mode::CBC */
697             int cipher_id, cipher_rounds;
698             symmetric_CBC state;
699             unsigned char pad[MAXBLOCKSIZE];
700             int padlen;
701             int padding_mode;
702             int direction;
703             } *Crypt__Mode__CBC;
704              
705             typedef struct ecb_struct { /* used by Crypt::Mode::ECB */
706             int cipher_id, cipher_rounds;
707             symmetric_ECB state;
708             unsigned char pad[MAXBLOCKSIZE];
709             int padlen;
710             int padding_mode;
711             int direction;
712             } *Crypt__Mode__ECB;
713              
714             typedef struct cfb_struct { /* used by Crypt::Mode::CFB */
715             int cipher_id, cipher_rounds;
716             symmetric_CFB state;
717             int direction;
718             } *Crypt__Mode__CFB;
719              
720             typedef struct ctr_struct { /* used by Crypt::Mode::CTR */
721             int cipher_id, cipher_rounds;
722             int ctr_mode_param;
723             symmetric_CTR state;
724             int direction;
725             } *Crypt__Mode__CTR;
726              
727             typedef struct f8_struct { /* used by Crypt::Mode::F8 */
728             int cipher_id, cipher_rounds;
729             symmetric_F8 state;
730             int direction;
731             } *Crypt__Mode__F8;
732              
733             typedef struct lrw_struct { /* used by Crypt::Mode::LRW */
734             int cipher_id, cipher_rounds;
735             symmetric_LRW state;
736             int direction;
737             } *Crypt__Mode__LRW;
738              
739             typedef struct ofb_struct { /* used by Crypt::Mode::OFB */
740             int cipher_id, cipher_rounds;
741             symmetric_OFB state;
742             int direction;
743             } *Crypt__Mode__OFB;
744              
745             typedef struct xts_struct { /* used by Crypt::Mode::XTS */
746             int cipher_id, cipher_rounds;
747             symmetric_xts state;
748             int direction;
749             } *Crypt__Mode__XTS;
750              
751             typedef struct prng_struct { /* used by Crypt::PRNG */
752             prng_state state;
753             struct ltc_prng_descriptor *desc;
754             IV last_pid;
755             } *Crypt__PRNG;
756              
757             typedef struct rsa_struct { /* used by Crypt::PK::RSA */
758             prng_state pstate;
759             int pindex;
760             IV last_pid;
761             rsa_key key;
762             } *Crypt__PK__RSA;
763              
764             typedef struct dsa_struct { /* used by Crypt::PK::DSA */
765             prng_state pstate;
766             int pindex;
767             IV last_pid;
768             dsa_key key;
769             } *Crypt__PK__DSA;
770              
771             typedef struct dh_struct { /* used by Crypt::PK::DH */
772             prng_state pstate;
773             int pindex;
774             IV last_pid;
775             dh_key key;
776             } *Crypt__PK__DH;
777              
778             typedef struct ecc_struct { /* used by Crypt::PK::ECC */
779             prng_state pstate;
780             int pindex;
781             IV last_pid;
782             ecc_key key;
783             } *Crypt__PK__ECC;
784              
785             typedef struct ed25519_struct { /* used by Crypt::PK::Ed25519 */
786             prng_state pstate;
787             int pindex;
788             IV last_pid;
789             curve25519_key key;
790             int initialized;
791             } *Crypt__PK__Ed25519;
792              
793             typedef struct x25519_struct { /* used by Crypt::PK::X25519 */
794             prng_state pstate;
795             int pindex;
796             IV last_pid;
797             curve25519_key key;
798             int initialized;
799             } *Crypt__PK__X25519;
800              
801             typedef struct ed448_struct { /* used by Crypt::PK::Ed448 */
802             prng_state pstate;
803             int pindex;
804             IV last_pid;
805             curve448_key key;
806             int initialized;
807             } *Crypt__PK__Ed448;
808              
809             typedef struct x448_struct { /* used by Crypt::PK::X448 */
810             prng_state pstate;
811             int pindex;
812             IV last_pid;
813             curve448_key key;
814             int initialized;
815             } *Crypt__PK__X448;
816              
817 64           STATIC int cryptx_internal_password_cb_getpw(void **p, unsigned long *l, void *u) {
818             dTHX; /* fetch context */
819 64           SV *passwd = u;
820 64           void *pwd = NULL;
821 64           STRLEN pwd_len = 0;
822              
823 64 50         if (p == NULL) {
824 0           *l = 0;
825 0           return 1;
826             }
827 64 50         if (passwd == NULL || !SvOK(passwd)) {
    50          
828 0           *p = NULL;
829 0           *l = 0;
830 0           return 1;
831             }
832 64           pwd = SvPVbyte(passwd, pwd_len);
833 64 50         if (pwd == NULL || pwd_len == 0) {
    50          
834 0           *p = NULL;
835 0           *l = 0;
836 0           return 1;
837             }
838 64           Newz(0, *p, pwd_len, unsigned char);
839 64 50         if (*p == NULL) {
840 0           *l = 0;
841 0           return 1;
842             }
843 64           Copy(pwd, *p, pwd_len, unsigned char);
844 64           *l = (unsigned long)pwd_len;
845              
846 64           return 0;
847             }
848              
849 401           STATIC void cryptx_internal_pk_prng_reseed(prng_state *state, int pindex, IV *last_pid) {
850             dTHX; /* fetch context */
851 401           IV curpid = (IV)PerlProc_getpid();
852             unsigned char entropy_buf[40];
853             int rv;
854              
855 401 50         if (*last_pid == curpid) return;
856              
857 0 0         if (rng_get_bytes(entropy_buf, sizeof(entropy_buf), NULL) != sizeof(entropy_buf)) {
858 0           croak("FATAL: rng_get_bytes failed");
859             }
860 0           rv = prng_descriptor[pindex].add_entropy(entropy_buf, sizeof(entropy_buf), state);
861 0 0         if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
862 0           rv = prng_descriptor[pindex].ready(state);
863 0 0         if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
864 0           zeromem(entropy_buf, sizeof(entropy_buf));
865 0           *last_pid = curpid;
866             }
867              
868 53           STATIC void cryptx_internal_prng_done(struct prng_struct *prng) {
869 53 50         if (prng != NULL && prng->desc != NULL && prng->desc->done != NULL) {
    50          
    50          
870 53           (void)prng->desc->done(&prng->state);
871             }
872 53           }
873              
874 36124           STATIC void cryptx_internal_prng_reseed(struct prng_struct *prng) {
875             dTHX; /* fetch context */
876 36124           IV curpid = (IV)PerlProc_getpid();
877             unsigned char entropy_buf[40];
878             int rv;
879              
880 36124 50         if (prng == NULL || prng->desc == NULL || prng->last_pid == curpid) return;
    50          
    50          
881              
882 0 0         if (rng_get_bytes(entropy_buf, sizeof(entropy_buf), NULL) != sizeof(entropy_buf)) {
883 0           croak("FATAL: rng_get_bytes failed");
884             }
885 0           rv = prng->desc->add_entropy(entropy_buf, sizeof(entropy_buf), &prng->state);
886 0           zeromem(entropy_buf, sizeof(entropy_buf));
887 0 0         if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
888 0           rv = prng->desc->ready(&prng->state);
889 0 0         if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
890 0           prng->last_pid = curpid;
891             }
892              
893 64           STATIC void cryptx_internal_password_cb_free(void *p) {
894             dTHX; /* fetch context */
895 64           Safefree(p);
896 64           return;
897             }
898              
899 1404           STATIC int cryptx_internal_mp2hex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) {
900             int len, rv;
901              
902 1404 50         if (mp_isneg(a) == MP_YES) {
903 0           *str = '\0';
904 0           return MP_VAL;
905             }
906              
907 1404           rv = mp_to_radix(a, str, maxlen, NULL, 16);
908 1404 50         if (rv != MP_OKAY) {
909 0           *str = '\0';
910 0           return rv;
911             }
912              
913 1404           len = (int)strlen(str);
914 1404 50         if (len > 0 && len % 2 && len < maxlen-2) {
    100          
    50          
915 280           memmove(str+1, str, len+1); /* incl. NUL byte */
916 280           *str = '0'; /* add leading zero */
917             }
918              
919 1404           len = (int)strlen(str);
920 1404 100         if (len < minlen && minlen < maxlen-1) {
    50          
921 6           memmove(str+(minlen-len), str, len+1); /* incl. NUL byte */
922 6           memset(str, '0', minlen-len); /* add leading zero */
923             }
924              
925 1404           return MP_OKAY;
926             }
927              
928 15241           STATIC size_t cryptx_internal_find_start(const char *name, char *ltcname, size_t ltclen)
929             {
930 15241           size_t i, start = 0;
931 15241 50         if (name == NULL || strlen(name) + 1 > ltclen) croak("FATAL: invalid name") ;
    50          
932             /* normalize */
933 110862 50         for (i = 0; i < ltclen && name[i] > 0; i++) {
    100          
934 95621 100         if (name[i] >= 'A' && name[i] <= 'Z') {
    100          
935 49664           ltcname[i] = name[i] + 32; /* lowecase */
936             }
937 45957 100         else if (name[i] == '_') {
938 1859           ltcname[i] = '-';
939             }
940             else {
941 44098           ltcname[i] = name[i];
942             }
943 95621 50         if (name[i] == ':') start = i + 1;
944             }
945 15241           return start;
946             }
947              
948 8779           STATIC int cryptx_internal_find_hash(const char *name)
949             {
950 8779           char ltcname[100] = { 0 };
951 8779           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
952             /* special cases */
953 8779 100         if (strcmp(ltcname + start, "ripemd128") == 0) return find_hash("rmd128");
954 8307 100         if (strcmp(ltcname + start, "ripemd160") == 0) return find_hash("rmd160");
955 7835 100         if (strcmp(ltcname + start, "ripemd256") == 0) return find_hash("rmd256");
956 7751 100         if (strcmp(ltcname + start, "ripemd320") == 0) return find_hash("rmd320");
957 7667 100         if (strcmp(ltcname + start, "tiger192") == 0) return find_hash("tiger");
958 7177 100         if (strcmp(ltcname + start, "chaes") == 0) return find_hash("chc_hash");
959 6993 50         if (strcmp(ltcname + start, "chc-hash") == 0) return find_hash("chc_hash");
960 6993           return find_hash(ltcname + start);
961             }
962              
963 6408           STATIC int cryptx_internal_find_cipher(const char *name)
964             {
965 6408           char ltcname[100] = { 0 };
966 6408           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
967             /* special cases */
968 6408 100         if (strcmp(ltcname + start, "des-ede") == 0) return find_cipher("3des");
969 6273 100         if (strcmp(ltcname + start, "saferp") == 0) return find_cipher("safer+");
970 6010           return find_cipher(ltcname + start);
971             }
972              
973 54           STATIC int cryptx_internal_find_prng(const char *name)
974             {
975 54           char ltcname[100] = { 0 };
976 54           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
977 54           return find_prng(ltcname + start);
978             }
979              
980             /* Math::BigInt::LTM related */
981             typedef mp_int * Math__BigInt__LTM;
982 181           STATIC SV * sv_from_mpi(mp_int *mpi) {
983             dTHX; /* fetch context */
984 181           SV *obj = newSV(0);
985 181           sv_setref_pv(obj, "Math::BigInt::LTM", (void*)mpi);
986 181           return obj;
987             }
988              
989 2           STATIC void cryptx_internal_ecc_oid_lookup(ecc_key *key)
990             {
991             int err;
992             unsigned i, j;
993             void *tmp;
994             const ltc_ecc_curve *cu;
995              
996 2           key->dp.oidlen = 0;
997 2 50         if ((err = ltc_mp.init(&tmp)) != CRYPT_OK) return;
998 52 100         for (cu = ltc_ecc_curves; cu->prime != NULL; cu++) {
999 51 50         if ((err = mp_read_radix(tmp, cu->prime, 16)) != CRYPT_OK) continue;
1000 51 100         if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue;
1001 2 50         if ((err = mp_read_radix(tmp, cu->order, 16)) != CRYPT_OK) continue;
1002 2 50         if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue;
1003 2 50         if ((err = mp_read_radix(tmp, cu->A, 16)) != CRYPT_OK) continue;
1004 2 50         if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue;
1005 2 50         if ((err = mp_read_radix(tmp, cu->B, 16)) != CRYPT_OK) continue;
1006 2 50         if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue;
1007 2 50         if ((err = mp_read_radix(tmp, cu->Gx, 16)) != CRYPT_OK) continue;
1008 2 50         if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue;
1009 2 50         if ((err = mp_read_radix(tmp, cu->Gy, 16)) != CRYPT_OK) continue;
1010 2 50         if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue;
1011 2 100         if (key->dp.cofactor != cu->cofactor) continue;
1012 1           break; /* found */
1013             }
1014 2           ltc_mp.deinit(tmp);
1015 2 100         if (cu->prime && cu->OID) {
    50          
1016 17 100         for (i = 0; i < 16; i++) key->dp.oid[i] = 0;
1017 13 100         for (i = 0, j = 0; i < strlen(cu->OID); i++) {
1018 12 100         if (cu->OID[i] == '.') {
1019 4 50         if (++j >= 16) return;
1020             }
1021 8 50         else if(cu->OID[i] >= '0' && cu->OID[i] <= '9') {
    50          
1022 8           key->dp.oid[j] = key->dp.oid[j] * 10 + (cu->OID[i] - '0');
1023             }
1024             else {
1025 0           return;
1026             }
1027             }
1028 1           key->dp.oidlen = j + 1;
1029             }
1030             }
1031              
1032 199           STATIC int cryptx_internal_ecc_set_curve_from_SV(ecc_key *key, SV *curve)
1033             {
1034             dTHX; /* fetch context */
1035             HV *hc, *h;
1036             SV *sv_crv, **pref;
1037             SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy, **sv_oid;
1038             char *ptr_crv;
1039             STRLEN len_crv;
1040             int err;
1041              
1042 199 50         if (!SvOK(curve)) croak("FATAL: undefined curve");
1043              
1044 199 50         if (SvPOK_spec(curve)) {
    100          
    50          
    50          
    0          
1045             /* string */
1046 197           ptr_crv = SvPV(curve, len_crv);
1047 197 50         if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register");
1048 197           pref = hv_fetch(hc, ptr_crv, (U32)len_crv, 0);
1049 197 50         if (pref && SvOK(*pref)) {
    0          
1050 0           sv_crv = *pref; /* found in %curve */
1051             }
1052             else {
1053 197           sv_crv = curve;
1054             }
1055             }
1056 2 50         else if (SvROK(curve) && SvTYPE(SvRV(curve)) == SVt_PVHV) {
    50          
1057             /* hashref */
1058 2           sv_crv = curve;
1059             }
1060             else {
1061 0           croak("FATAL: curve has to be a string or a hashref");
1062             }
1063              
1064 199 50         if (SvPOK_spec(sv_crv)) {
    100          
    50          
    50          
    0          
1065             /* string - curve name */
1066             const ltc_ecc_curve *cu;
1067 197           ptr_crv = SvPV(sv_crv, len_crv);
1068 197 50         if (ecc_find_curve(ptr_crv, &cu) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ptr_crv);
1069 197           return ecc_set_curve(cu, key);
1070             }
1071             else {
1072             /* hashref */
1073 2           ltc_ecc_curve cu = { 0 };
1074              
1075 2 50         if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref");
1076              
1077 2 50         if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime");
1078 2 50         if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A");
1079 2 50         if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B");
1080 2 50         if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order");
1081 2 50         if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx");
1082 2 50         if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy");
1083 2 50         if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor");
1084              
1085 2 50         if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime");
1086 2 50         if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A");
1087 2 50         if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B");
1088 2 50         if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order");
1089 2 50         if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx");
1090 2 50         if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy");
1091 2 50         if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor");
1092              
1093 2           sv_oid = hv_fetchs(h, "oid", 0); /* 'oid' is optional */
1094 2 50         cu.OID = (sv_oid && SvOK(*sv_oid)) ? SvPV_nolen(*sv_oid) : NULL;
    0          
1095              
1096 2           cu.prime = SvPV_nolen(*sv_prime);
1097 2           cu.A = SvPV_nolen(*sv_A);
1098 2           cu.B = SvPV_nolen(*sv_B);
1099 2           cu.order = SvPV_nolen(*sv_order);
1100 2           cu.Gx = SvPV_nolen(*sv_Gx);
1101 2           cu.Gy = SvPV_nolen(*sv_Gy);
1102 2           cu.cofactor = (unsigned long)SvUV(*sv_cofactor);
1103              
1104 2 50         if ((err = ecc_set_curve(&cu, key)) != CRYPT_OK) return err;
1105 2 50         if (key->dp.oidlen == 0) cryptx_internal_ecc_oid_lookup(key);
1106 2           return CRYPT_OK;
1107             }
1108             }
1109              
1110             MODULE = CryptX PACKAGE = CryptX PREFIX = CryptX_
1111              
1112             PROTOTYPES: DISABLE
1113              
1114             BOOT:
1115 156 50         if(register_all_ciphers() != CRYPT_OK) { croak("FATAL: register_all_ciphers failed"); }
1116 156 50         if(register_all_hashes() != CRYPT_OK) { croak("FATAL: register_all_hashes failed"); }
1117 156 50         if(register_all_prngs() != CRYPT_OK) { croak("FATAL: register_all_prngs failed"); }
1118 156 50         if(crypt_mp_init("ltm") != CRYPT_OK) { croak("FATAL: crypt_mp_init failed"); }
1119              
1120             SV *
1121             CryptX__ltc_build_settings()
1122             CODE:
1123 1           RETVAL = newSVpv(crypt_build_settings, 0);
1124             OUTPUT:
1125             RETVAL
1126              
1127             SV *
1128             CryptX__ltc_mp_name()
1129             CODE:
1130 1           RETVAL = newSVpv(ltc_mp.name, 0);
1131             OUTPUT:
1132             RETVAL
1133              
1134             int
1135             CryptX__ltc_mp_bits_per_digit()
1136             CODE:
1137 1 50         RETVAL = ltc_mp.bits_per_digit;
1138             OUTPUT:
1139             RETVAL
1140              
1141             MODULE = CryptX PACKAGE = Crypt::Misc
1142              
1143             PROTOTYPES: DISABLE
1144              
1145             SV *
1146             _radix_to_bin(SV *in, int radix)
1147             CODE:
1148             {
1149             STRLEN in_len, len;
1150             unsigned char *out_data;
1151             char *in_data;
1152             mp_int mpi;
1153              
1154 265 50         if (!SvPOK_spec(in) || radix < 2 || radix > 64) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
    50          
    50          
1155 265           in_data = SvPVbyte(in, in_len);
1156 265 50         if (in_len > 0 && memchr(in_data, '\0', in_len) != NULL) XSRETURN_UNDEF;
    50          
1157 265 50         if (mp_init(&mpi) != MP_OKAY) XSRETURN_UNDEF;
1158 265 50         if (in_len == 0) {
1159 0           RETVAL = newSVpvn("", 0);
1160             }
1161 265 50         else if (mp_read_radix(&mpi, in_data, radix) == MP_OKAY) {
1162 265           len = mp_ubin_size(&mpi);
1163 265 50         if (len == 0) {
1164 0           RETVAL = newSVpvn("", 0);
1165             }
1166             else {
1167 265           RETVAL = NEWSV(0, len); /* avoid zero! */
1168 265           SvPOK_only(RETVAL);
1169 265           SvCUR_set(RETVAL, len);
1170 265           out_data = (unsigned char *)SvPVX(RETVAL);
1171 265 50         if (mp_to_ubin(&mpi, out_data, len, NULL) != MP_OKAY) {
1172 0           SvREFCNT_dec(RETVAL);
1173 0           RETVAL = newSVpvn(NULL, 0); /* undef */
1174             }
1175             }
1176             }
1177             else {
1178 0           RETVAL = newSVpvn(NULL, 0); /* undef */
1179             }
1180 265           mp_clear(&mpi);
1181             }
1182             OUTPUT:
1183             RETVAL
1184              
1185             SV *
1186             _bin_to_radix(SV *in, int radix)
1187             CODE:
1188             {
1189             STRLEN len;
1190             unsigned char *in_data;
1191             char *out_data;
1192             mp_int mpi, tmp;
1193             mp_digit d;
1194             mp_err merr;
1195 290           int digits = 0;
1196              
1197 290 50         if (!SvPOK_spec(in) || radix < 2 || radix > 64) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
    50          
    50          
1198 290           in_data = (unsigned char *) SvPVbyte(in, len);
1199 290 50         if (mp_init_multi(&mpi, &tmp, NULL) != MP_OKAY) XSRETURN_UNDEF;
1200 290 50         if (len == 0) {
1201 0           RETVAL = newSVpvn("", 0);
1202             }
1203             else {
1204 290 50         if (mp_from_ubin(&mpi, in_data, (size_t)len) == MP_OKAY) {
1205 290           merr = mp_copy(&mpi, &tmp);
1206 5655 50         while (merr == MP_OKAY && mp_iszero(&tmp) == MP_NO) {
    100          
1207 5365           merr = mp_div_d(&tmp, (mp_digit)radix, &tmp, &d);
1208 5365           digits++;
1209             }
1210 290 50         if (merr != MP_OKAY) {
1211 0           RETVAL = newSVpvn(NULL, 0); /* undef */
1212             }
1213 290 100         else if (digits == 0) {
1214 25           RETVAL = newSVpvn("", 0);
1215             }
1216             else {
1217 265           RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */
1218 265           SvPOK_only(RETVAL);
1219 265           out_data = SvPVX(RETVAL);
1220 265 50         if (mp_to_radix(&mpi, out_data, digits + 2, NULL, radix) == MP_OKAY) {
1221 265           SvCUR_set(RETVAL, strlen(out_data));
1222             }
1223             else {
1224 0           SvREFCNT_dec(RETVAL);
1225 0           RETVAL = newSVpvn(NULL, 0); /* undef */
1226             }
1227             }
1228             }
1229             else {
1230 0           RETVAL = newSVpvn(NULL, 0); /* undef */
1231             }
1232             }
1233 290           mp_clear_multi(&tmp, &mpi, NULL);
1234             }
1235             OUTPUT:
1236             RETVAL
1237              
1238             SV *
1239             encode_b64(SV * in)
1240             ALIAS:
1241             encode_b64u = 1
1242             CODE:
1243             {
1244             int rv;
1245             STRLEN in_len;
1246             unsigned long out_len;
1247             unsigned char *in_data;
1248             char *out_data;
1249              
1250 154 100         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    100          
    50          
    50          
    50          
1251 153           in_data = (unsigned char *) SvPVbyte(in, in_len);
1252 153 50         if (in_len == 0) {
1253 0           RETVAL = newSVpvn("", 0);
1254             }
1255             else {
1256 153           out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1);
1257 153           RETVAL = NEWSV(0, out_len); /* avoid zero! */
1258 153           SvPOK_only(RETVAL);
1259 153           out_data = SvPVX(RETVAL);
1260 153 100         if (ix == 1)
1261 59           rv = base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len);
1262             else
1263 94           rv = base64_encode(in_data, (unsigned long)in_len, out_data, &out_len);
1264 153 50         if (rv != CRYPT_OK) {
1265 0           SvREFCNT_dec(RETVAL);
1266 0           XSRETURN_UNDEF;
1267             }
1268 153           SvCUR_set(RETVAL, out_len);
1269             }
1270             }
1271             OUTPUT:
1272             RETVAL
1273              
1274             SV *
1275             decode_b64(SV * in)
1276             ALIAS:
1277             decode_b64u = 1
1278             CODE:
1279             {
1280             int rv;
1281             STRLEN in_len;
1282             unsigned long out_len;
1283             unsigned char *out_data;
1284             char *in_data;
1285              
1286 425 100         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    100          
    50          
    50          
    50          
1287 419           in_data = SvPVbyte(in, in_len);
1288 419 50         if (in_len == 0) {
1289 0           RETVAL = newSVpvn("", 0);
1290             }
1291             else {
1292 419 100         if (cryptx_internal_input_has_no_payload(in_data, in_len)) XSRETURN_UNDEF;
1293 414           out_len = (unsigned long)in_len;
1294 414           RETVAL = NEWSV(0, out_len); /* avoid zero! */
1295 414           SvPOK_only(RETVAL);
1296 414           out_data = (unsigned char *)SvPVX(RETVAL);
1297 414 100         if (ix == 1)
1298 76           rv = base64url_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len);
1299             else
1300 338           rv = base64_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len);
1301 414 50         if (rv != CRYPT_OK) {
1302 0           SvREFCNT_dec(RETVAL);
1303 0           XSRETURN_UNDEF;
1304             }
1305 414           SvCUR_set(RETVAL, out_len);
1306             }
1307             }
1308             OUTPUT:
1309             RETVAL
1310              
1311             SV *
1312             encode_b32r(SV *in)
1313             ALIAS:
1314             encode_b32b = 1
1315             encode_b32z = 2
1316             encode_b32c = 3
1317             CODE:
1318             {
1319             STRLEN in_len;
1320             unsigned long out_len;
1321             unsigned char *in_data;
1322             char *out_data;
1323 235           int id = -1, err;
1324              
1325 235 100         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    100          
    50          
    50          
    50          
1326 234 100         if (ix == 0) id = BASE32_RFC4648;
1327 234 100         if (ix == 1) id = BASE32_BASE32HEX;
1328 234 100         if (ix == 2) id = BASE32_ZBASE32;
1329 234 100         if (ix == 3) id = BASE32_CROCKFORD;
1330 234 50         if (id == -1) XSRETURN_UNDEF;
1331 234           in_data = (unsigned char *) SvPVbyte(in, in_len);
1332 234 50         if (in_len == 0) {
1333 0           RETVAL = newSVpvn("", 0);
1334             }
1335             else {
1336 234           out_len = (unsigned long)((8 * in_len + 4) / 5 + 1);
1337 234           RETVAL = NEWSV(0, out_len); /* avoid zero! */
1338 234           SvPOK_only(RETVAL);
1339 234           out_data = SvPVX(RETVAL);
1340 234           err = base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id);
1341 234 50         if (err != CRYPT_OK) {
1342 0           SvREFCNT_dec(RETVAL);
1343 0           XSRETURN_UNDEF;
1344             }
1345 234           SvCUR_set(RETVAL, out_len);
1346             }
1347             }
1348             OUTPUT:
1349             RETVAL
1350              
1351             SV *
1352             decode_b32r(SV *in)
1353             ALIAS:
1354             decode_b32b = 1
1355             decode_b32z = 2
1356             decode_b32c = 3
1357             CODE:
1358             {
1359             STRLEN in_len;
1360             unsigned long out_len;
1361             unsigned char *out_data;
1362             char *in_data;
1363 237           int id = -1, err;
1364              
1365 241 100         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
1366 236 100         if (ix == 0) id = BASE32_RFC4648;
1367 236 100         if (ix == 1) id = BASE32_BASE32HEX;
1368 236 100         if (ix == 2) id = BASE32_ZBASE32;
1369 236 100         if (ix == 3) id = BASE32_CROCKFORD;
1370 236 50         if (id == -1) XSRETURN_UNDEF;
1371 236           in_data = SvPVbyte(in, in_len);
1372 236 50         if (in_len == 0) {
1373 0           RETVAL = newSVpvn("", 0);
1374             }
1375             else {
1376 236 100         if (cryptx_internal_input_has_no_payload(in_data, in_len)) XSRETURN_UNDEF;
1377 232           out_len = (unsigned long)in_len;
1378 232           RETVAL = NEWSV(0, out_len); /* avoid zero! */
1379 232           SvPOK_only(RETVAL);
1380 232           out_data = (unsigned char *)SvPVX(RETVAL);
1381 232           err = base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id);
1382 232 50         if (err != CRYPT_OK) {
1383 0           SvREFCNT_dec(RETVAL);
1384 0           XSRETURN_UNDEF;
1385             }
1386 232           SvCUR_set(RETVAL, out_len);
1387             }
1388             }
1389             OUTPUT:
1390             RETVAL
1391              
1392             SV *
1393             increment_octets_le(SV * in)
1394             CODE:
1395             {
1396 6           STRLEN len, i = 0;
1397             unsigned char *out_data, *in_data;
1398              
1399 6 50         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
1400 6           in_data = (unsigned char *)SvPVbyte(in, len);
1401 6 50         if (len == 0) {
1402 0           RETVAL = newSVpvn("", 0);
1403             }
1404             else {
1405 6           RETVAL = NEWSV(0, len); /* avoid zero! */
1406 6           SvPOK_only(RETVAL);
1407 6           SvCUR_set(RETVAL, len);
1408 6           out_data = (unsigned char *)SvPVX(RETVAL);
1409 6           Copy(in_data, out_data, len, unsigned char);
1410 13 100         while (i < len) {
1411 11           out_data[i]++;
1412 11 100         if (0 != out_data[i]) break;
1413 7           i++;
1414             }
1415 6 100         if (i == len) {
1416 2           SvREFCNT_dec(RETVAL);
1417 2           croak("FATAL: increment_octets_le overflow");
1418             }
1419             }
1420             }
1421             OUTPUT:
1422             RETVAL
1423              
1424             SV *
1425             increment_octets_be(SV * in)
1426             CODE:
1427             {
1428 8           STRLEN len, i = 0;
1429             unsigned char *out_data, *in_data;
1430              
1431 8 50         if (!SvPOK_spec(in)) XSRETURN_UNDEF;
    100          
    50          
    50          
    50          
1432 8           in_data = (unsigned char *)SvPVbyte(in, len);
1433 8 50         if (len == 0) {
1434 0           RETVAL = newSVpvn("", 0);
1435             }
1436             else {
1437 8           RETVAL = NEWSV(0, len); /* avoid zero! */
1438 8           SvPOK_only(RETVAL);
1439 8           SvCUR_set(RETVAL, len);
1440 8           out_data = (unsigned char *)SvPVX(RETVAL);
1441 8           Copy(in_data, out_data, len, unsigned char);
1442 15 100         while (i < len) {
1443 13           out_data[len - 1 - i]++;
1444 13 100         if (0 != out_data[len - 1 - i]) break;
1445 7           i++;
1446             }
1447 8 100         if (i == len) {
1448 2           SvREFCNT_dec(RETVAL);
1449 2           croak("FATAL: increment_octets_be overflow");
1450             }
1451             }
1452             }
1453             OUTPUT:
1454             RETVAL
1455              
1456             SV *
1457             slow_eq(SV *a, SV *b)
1458             CODE:
1459             {
1460             STRLEN a_len, b_len;
1461             unsigned char *a_data, *b_data;
1462             const void *first;
1463 9           int result = 0;
1464              
1465 9 100         if (!SvPOK_spec(a) || !SvPOK_spec(b)) XSRETURN_UNDEF;
    50          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
1466 8           a_data = (unsigned char *)SvPVbyte(a, a_len);
1467 8           b_data = (unsigned char *)SvPVbyte(b, b_len);
1468 8           first = a_data;
1469 8 100         if (a_len != b_len) { first = b_data; result = 1; }
1470 8           result |= mem_neq(first, b_data, b_len);
1471 8           RETVAL = newSViv(result == 0 ? 1 : 0);
1472             }
1473             OUTPUT:
1474             RETVAL
1475              
1476             ###############################################################################
1477              
1478             INCLUDE: inc/CryptX_ASN1.xs.inc
1479             INCLUDE: inc/CryptX_Digest.xs.inc
1480             INCLUDE: inc/CryptX_Digest_SHAKE.xs.inc
1481             INCLUDE: inc/CryptX_Digest_TurboSHAKE.xs.inc
1482             INCLUDE: inc/CryptX_Digest_KangarooTwelve.xs.inc
1483             INCLUDE: inc/CryptX_Cipher.xs.inc
1484              
1485             INCLUDE: inc/CryptX_Checksum_Adler32.xs.inc
1486             INCLUDE: inc/CryptX_Checksum_CRC32.xs.inc
1487              
1488             INCLUDE: inc/CryptX_AuthEnc_EAX.xs.inc
1489             INCLUDE: inc/CryptX_AuthEnc_GCM.xs.inc
1490             INCLUDE: inc/CryptX_AuthEnc_OCB.xs.inc
1491             INCLUDE: inc/CryptX_AuthEnc_CCM.xs.inc
1492             INCLUDE: inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc
1493             INCLUDE: inc/CryptX_AuthEnc_SIV.xs.inc
1494             INCLUDE: inc/CryptX_AuthEnc_GCMSIV.xs.inc
1495              
1496             INCLUDE: inc/CryptX_Stream_ChaCha.xs.inc
1497             INCLUDE: inc/CryptX_Stream_XChaCha.xs.inc
1498             INCLUDE: inc/CryptX_Stream_Salsa20.xs.inc
1499             INCLUDE: inc/CryptX_Stream_XSalsa20.xs.inc
1500             INCLUDE: inc/CryptX_Stream_RC4.xs.inc
1501             INCLUDE: inc/CryptX_Stream_Sober128.xs.inc
1502             INCLUDE: inc/CryptX_Stream_Sosemanuk.xs.inc
1503             INCLUDE: inc/CryptX_Stream_Rabbit.xs.inc
1504              
1505             INCLUDE: inc/CryptX_Mac_F9.xs.inc
1506             INCLUDE: inc/CryptX_Mac_HMAC.xs.inc
1507             INCLUDE: inc/CryptX_Mac_OMAC.xs.inc
1508             INCLUDE: inc/CryptX_Mac_Pelican.xs.inc
1509             INCLUDE: inc/CryptX_Mac_PMAC.xs.inc
1510             INCLUDE: inc/CryptX_Mac_XCBC.xs.inc
1511             INCLUDE: inc/CryptX_Mac_Poly1305.xs.inc
1512             INCLUDE: inc/CryptX_Mac_BLAKE2s.xs.inc
1513             INCLUDE: inc/CryptX_Mac_BLAKE2b.xs.inc
1514             INCLUDE: inc/CryptX_Mac_KMAC.xs.inc
1515              
1516             INCLUDE: inc/CryptX_Mode_CBC.xs.inc
1517             INCLUDE: inc/CryptX_Mode_ECB.xs.inc
1518             INCLUDE: inc/CryptX_Mode_CFB.xs.inc
1519             INCLUDE: inc/CryptX_Mode_OFB.xs.inc
1520             INCLUDE: inc/CryptX_Mode_CTR.xs.inc
1521             #INCLUDE: inc/CryptX_Mode_F8.xs.inc
1522             #INCLUDE: inc/CryptX_Mode_LRW.xs.inc
1523             #INCLUDE: inc/CryptX_Mode_XTS.xs.inc
1524              
1525             INCLUDE: inc/CryptX_PRNG.xs.inc
1526              
1527             INCLUDE: inc/CryptX_PK_RSA.xs.inc
1528             INCLUDE: inc/CryptX_PK_DSA.xs.inc
1529             INCLUDE: inc/CryptX_PK_DH.xs.inc
1530             INCLUDE: inc/CryptX_PK_ECC.xs.inc
1531             INCLUDE: inc/CryptX_PK_Ed25519.xs.inc
1532             INCLUDE: inc/CryptX_PK_X25519.xs.inc
1533             INCLUDE: inc/CryptX_PK_Ed448.xs.inc
1534             INCLUDE: inc/CryptX_PK_X448.xs.inc
1535              
1536             INCLUDE: inc/CryptX_KeyDerivation.xs.inc
1537              
1538             INCLUDE: inc/CryptX_BigInt_LTM.xs.inc