File Coverage

CryptX.xs
Criterion Covered Total %
statement 214 275 77.8
branch 168 334 50.3
condition n/a
subroutine n/a
pod n/a
total 382 609 62.7


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             #undef LTC_SOURCE
22             #include "tomcrypt.h"
23             #include "tommath.h"
24              
25             typedef adler32_state *Crypt__Checksum__Adler32;
26             typedef crc32_state *Crypt__Checksum__CRC32;
27              
28             typedef ccm_state *Crypt__AuthEnc__CCM;
29             typedef eax_state *Crypt__AuthEnc__EAX;
30             typedef gcm_state *Crypt__AuthEnc__GCM;
31             typedef chacha20poly1305_state *Crypt__AuthEnc__ChaCha20Poly1305;
32             typedef ocb3_state *Crypt__AuthEnc__OCB;
33              
34             typedef chacha_state *Crypt__Stream__ChaCha;
35             typedef salsa20_state *Crypt__Stream__Salsa20;
36             typedef sosemanuk_state *Crypt__Stream__Sosemanuk;
37             typedef rabbit_state *Crypt__Stream__Rabbit;
38             typedef rc4_state *Crypt__Stream__RC4;
39             typedef sober128_state *Crypt__Stream__Sober128;
40              
41             typedef f9_state *Crypt__Mac__F9;
42             typedef hmac_state *Crypt__Mac__HMAC;
43             typedef omac_state *Crypt__Mac__OMAC;
44             typedef pelican_state *Crypt__Mac__Pelican;
45             typedef pmac_state *Crypt__Mac__PMAC;
46             typedef xcbc_state *Crypt__Mac__XCBC;
47             typedef poly1305_state *Crypt__Mac__Poly1305;
48             typedef blake2smac_state *Crypt__Mac__BLAKE2s;
49             typedef blake2bmac_state *Crypt__Mac__BLAKE2b;
50              
51             typedef struct cipher_struct { /* used by Crypt::Cipher */
52             symmetric_key skey;
53             struct ltc_cipher_descriptor *desc;
54             } *Crypt__Cipher;
55              
56             typedef struct digest_struct { /* used by Crypt::Digest */
57             hash_state state;
58             struct ltc_hash_descriptor *desc;
59             } *Crypt__Digest;
60              
61             typedef struct digest_shake_struct { /* used by Crypt::Digest::SHAKE */
62             hash_state state;
63             int num;
64             } *Crypt__Digest__SHAKE;
65              
66             typedef struct cbc_struct { /* used by Crypt::Mode::CBC */
67             int cipher_id, cipher_rounds;
68             symmetric_CBC state;
69             unsigned char pad[MAXBLOCKSIZE];
70             int padlen;
71             int padding_mode;
72             int direction;
73             } *Crypt__Mode__CBC;
74              
75             typedef struct ecb_struct { /* used by Crypt::Mode::ECB */
76             int cipher_id, cipher_rounds;
77             symmetric_ECB state;
78             unsigned char pad[MAXBLOCKSIZE];
79             int padlen;
80             int padding_mode;
81             int direction;
82             } *Crypt__Mode__ECB;
83              
84             typedef struct cfb_struct { /* used by Crypt::Mode::CFB */
85             int cipher_id, cipher_rounds;
86             symmetric_CFB state;
87             int direction;
88             } *Crypt__Mode__CFB;
89              
90             typedef struct ctr_struct { /* used by Crypt::Mode::CTR */
91             int cipher_id, cipher_rounds;
92             int ctr_mode_param;
93             symmetric_CTR state;
94             int direction;
95             } *Crypt__Mode__CTR;
96              
97             typedef struct f8_struct { /* used by Crypt::Mode::F8 */
98             int cipher_id, cipher_rounds;
99             symmetric_F8 state;
100             int direction;
101             } *Crypt__Mode__F8;
102              
103             typedef struct lrw_struct { /* used by Crypt::Mode::LRW */
104             int cipher_id, cipher_rounds;
105             symmetric_LRW state;
106             int direction;
107             } *Crypt__Mode__LRW;
108              
109             typedef struct ofb_struct { /* used by Crypt::Mode::OFB */
110             int cipher_id, cipher_rounds;
111             symmetric_OFB state;
112             int direction;
113             } *Crypt__Mode__OFB;
114              
115             typedef struct xts_struct { /* used by Crypt::Mode::XTS */
116             int cipher_id, cipher_rounds;
117             symmetric_xts state;
118             int direction;
119             } *Crypt__Mode__XTS;
120              
121             typedef struct prng_struct { /* used by Crypt::PRNG */
122             prng_state state;
123             struct ltc_prng_descriptor *desc;
124             IV last_pid;
125             } *Crypt__PRNG;
126              
127             typedef struct rsa_struct { /* used by Crypt::PK::RSA */
128             prng_state pstate;
129             int pindex;
130             rsa_key key;
131             } *Crypt__PK__RSA;
132              
133             typedef struct dsa_struct { /* used by Crypt::PK::DSA */
134             prng_state pstate;
135             int pindex;
136             dsa_key key;
137             } *Crypt__PK__DSA;
138              
139             typedef struct dh_struct { /* used by Crypt::PK::DH */
140             prng_state pstate;
141             int pindex;
142             dh_key key;
143             } *Crypt__PK__DH;
144              
145             typedef struct ecc_struct { /* used by Crypt::PK::ECC */
146             prng_state pstate;
147             int pindex;
148             ecc_key key;
149             } *Crypt__PK__ECC;
150              
151             typedef struct ed25519_struct { /* used by Crypt::PK::Ed25519 */
152             prng_state pstate;
153             int pindex;
154             curve25519_key key;
155             int initialized;
156             } *Crypt__PK__Ed25519;
157              
158             typedef struct x25519_struct { /* used by Crypt::PK::X25519 */
159             prng_state pstate;
160             int pindex;
161             curve25519_key key;
162             int initialized;
163             } *Crypt__PK__X25519;
164              
165 970           STATIC int cryptx_internal_mp2hex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) {
166             int len, rv;
167              
168 970 50         if (mp_isneg(a) == MP_YES) {
169 0           *str = '\0';
170 0           return MP_VAL;
171             }
172              
173 970           rv = mp_toradix_n(a, str, 16, maxlen);
174 970 50         if (rv != MP_OKAY) {
175 0           *str = '\0';
176 0           return rv;
177             }
178              
179 970           len = (int)strlen(str);
180 970 50         if (len > 0 && len % 2 && len < maxlen-2) {
    100          
    50          
181 189           memmove(str+1, str, len+1); /* incl. NUL byte */
182 189           *str = '0'; /* add leading zero */
183             }
184              
185 970           len = (int)strlen(str);
186 970 100         if (len < minlen && minlen < maxlen-1) {
    50          
187 1           memmove(str+(minlen-len), str, len+1); /* incl. NUL byte */
188 1           memset(str, '0', minlen-len); /* add leading zero */
189             }
190              
191 970           return MP_OKAY;
192             }
193              
194 14431           STATIC size_t cryptx_internal_find_start(const char *name, char *ltcname, size_t ltclen)
195             {
196 14431           size_t i, start = 0;
197 14431 50         if (name == NULL || strlen(name) + 1 > ltclen) croak("FATAL: invalid name") ;
    50          
198             /* normalize */
199 133345 50         for (i = 0; i < ltclen && name[i] > 0; i++) {
    100          
200 118914 100         if (name[i] >= 'A' && name[i] <= 'Z') {
    100          
201 50977           ltcname[i] = name[i] + 32; /* lowecase */
202             }
203 67937 100         else if (name[i] == '_') {
204 1719           ltcname[i] = '-';
205             }
206             else {
207 66218           ltcname[i] = name[i];
208             }
209 118914 100         if (name[i] == ':') start = i + 1;
210             }
211 14431           return start;
212             }
213              
214 8325           STATIC int cryptx_internal_find_hash(const char *name)
215             {
216 8325           char ltcname[100] = { 0 };
217 8325           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
218             /* special cases */
219 8325 100         if (strcmp(ltcname + start, "ripemd128") == 0) return find_hash("rmd128");
220 7861 100         if (strcmp(ltcname + start, "ripemd160") == 0) return find_hash("rmd160");
221 7397 100         if (strcmp(ltcname + start, "ripemd256") == 0) return find_hash("rmd256");
222 7321 100         if (strcmp(ltcname + start, "ripemd320") == 0) return find_hash("rmd320");
223 7245 100         if (strcmp(ltcname + start, "tiger192") == 0) return find_hash("tiger");
224 6763 100         if (strcmp(ltcname + start, "chaes") == 0) return find_hash("chc_hash");
225 6587 50         if (strcmp(ltcname + start, "chc-hash") == 0) return find_hash("chc_hash");
226 8325           return find_hash(ltcname + start);
227             }
228              
229 6093           STATIC int cryptx_internal_find_cipher(const char *name)
230             {
231 6093           char ltcname[100] = { 0 };
232 6093           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
233             /* special cases */
234 6093 100         if (strcmp(ltcname + start, "des-ede") == 0) return find_cipher("3des");
235 5962 100         if (strcmp(ltcname + start, "saferp") == 0) return find_cipher("safer+");
236 6093           return find_cipher(ltcname + start);
237             }
238              
239 13           STATIC int cryptx_internal_find_prng(const char *name)
240             {
241 13           char ltcname[100] = { 0 };
242 13           size_t start = cryptx_internal_find_start(name, ltcname, sizeof(ltcname) - 1);
243 13           return find_prng(ltcname + start);
244             }
245              
246             /* Math::BigInt::LTM related */
247             typedef mp_int * Math__BigInt__LTM;
248 5           STATIC SV * sv_from_mpi(mp_int *mpi) {
249             dTHX; /* fetch context */
250 5           SV *obj = newSV(0);
251 5           sv_setref_pv(obj, "Math::BigInt::LTM", (void*)mpi);
252 5           return obj;
253             }
254              
255 2           STATIC void cryptx_internal_ecc_oid_lookup(ecc_key *key)
256             {
257             int err;
258             unsigned i, j;
259             void *tmp;
260             const ltc_ecc_curve *cu;
261              
262 2           key->dp.oidlen = 0;
263 2 50         if ((err = ltc_mp.init(&tmp)) != CRYPT_OK) return;
264 51 100         for (cu = ltc_ecc_curves; cu->prime != NULL; cu++) {
265 50 50         if ((err = mp_read_radix(tmp, cu->prime, 16)) != CRYPT_OK) continue;
266 50 100         if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue;
267 2 50         if ((err = mp_read_radix(tmp, cu->order, 16)) != CRYPT_OK) continue;
268 2 50         if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue;
269 2 50         if ((err = mp_read_radix(tmp, cu->A, 16)) != CRYPT_OK) continue;
270 2 50         if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue;
271 2 50         if ((err = mp_read_radix(tmp, cu->B, 16)) != CRYPT_OK) continue;
272 2 50         if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue;
273 2 50         if ((err = mp_read_radix(tmp, cu->Gx, 16)) != CRYPT_OK) continue;
274 2 50         if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue;
275 2 50         if ((err = mp_read_radix(tmp, cu->Gy, 16)) != CRYPT_OK) continue;
276 2 50         if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue;
277 2 100         if (key->dp.cofactor != cu->cofactor) continue;
278 1           break; /* found */
279             }
280 2           ltc_mp.deinit(tmp);
281 2 100         if (cu->prime && cu->OID) {
    50          
282 17 100         for (i = 0; i < 16; i++) key->dp.oid[i] = 0;
283 13 100         for (i = 0, j = 0; i < strlen(cu->OID); i++) {
284 12 100         if (cu->OID[i] == '.') {
285 4 50         if (++j >= 16) return;
286             }
287 8 50         else if(cu->OID[i] >= '0' && cu->OID[i] <= '9') {
    50          
288 8           key->dp.oid[j] = key->dp.oid[j] * 10 + (cu->OID[i] - '0');
289             }
290             else {
291 0           return;
292             }
293             }
294 2           key->dp.oidlen = j + 1;
295             }
296             }
297              
298 190           STATIC int cryptx_internal_ecc_set_curve_from_SV(ecc_key *key, SV *curve)
299             {
300             dTHX; /* fetch context */
301             HV *hc, *h;
302             SV *sv_crv, **pref;
303             SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy, **sv_oid;
304             char *ptr_crv;
305             STRLEN len_crv;
306             int err;
307              
308 190 50         if (!SvOK(curve)) croak("FATAL: undefined curve");
    0          
    0          
309              
310 190 100         if (SvPOK(curve)) {
311             /* string */
312 188 50         ptr_crv = SvPV(curve, len_crv);
313 188 50         if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register");
314 188           pref = hv_fetch(hc, ptr_crv, (U32)len_crv, 0);
315 188 50         if (pref && SvOK(*pref)) {
    0          
    0          
    0          
316 0           sv_crv = *pref; /* found in %curve */
317             }
318             else {
319 188           sv_crv = curve;
320             }
321             }
322 2 50         else if (SvROK(curve) && SvTYPE(SvRV(curve)) == SVt_PVHV) {
    50          
323             /* hashref */
324 2           sv_crv = curve;
325             }
326             else {
327 0           croak("FATAL: curve has to be a string or a hashref");
328             }
329              
330 190 100         if (SvPOK(sv_crv)) {
331             /* string - curve name */
332             const ltc_ecc_curve *cu;
333 188 50         ptr_crv = SvPV(sv_crv, len_crv);
334 188 50         if (ecc_find_curve(ptr_crv, &cu) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ptr_crv);
335 188           return ecc_set_curve(cu, key);
336             }
337             else {
338             /* hashref */
339 2           ltc_ecc_curve cu = { 0 };
340              
341 2 50         if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref");
342              
343 2 50         if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime");
344 2 50         if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A");
345 2 50         if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B");
346 2 50         if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order");
347 2 50         if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx");
348 2 50         if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy");
349 2 50         if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor");
350              
351 2 50         if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime");
    0          
    0          
352 2 50         if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A");
    0          
    0          
353 2 50         if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B");
    0          
    0          
354 2 50         if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order");
    0          
    0          
355 2 50         if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx");
    0          
    0          
356 2 50         if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy");
    0          
    0          
357 2 50         if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor");
    0          
    0          
358              
359 2           sv_oid = hv_fetchs(h, "oid", 0); /* 'oid' is optional */
360 2 50         cu.OID = (sv_oid && SvOK(*sv_oid)) ? SvPV_nolen(*sv_oid) : NULL;
    0          
    0          
    0          
    0          
361              
362 2 50         cu.prime = SvPV_nolen(*sv_prime);
363 2 50         cu.A = SvPV_nolen(*sv_A);
364 2 50         cu.B = SvPV_nolen(*sv_B);
365 2 50         cu.order = SvPV_nolen(*sv_order);
366 2 50         cu.Gx = SvPV_nolen(*sv_Gx);
367 2 50         cu.Gy = SvPV_nolen(*sv_Gy);
368 2 50         cu.cofactor = (unsigned long)SvUV(*sv_cofactor);
369              
370 2 50         if ((err = ecc_set_curve(&cu, key)) != CRYPT_OK) return err;
371 2 50         if (key->dp.oidlen == 0) cryptx_internal_ecc_oid_lookup(key);
372 190           return CRYPT_OK;
373             }
374             }
375              
376             MODULE = CryptX PACKAGE = CryptX PREFIX = CryptX_
377              
378             PROTOTYPES: DISABLE
379              
380             BOOT:
381 129 50         if(register_all_ciphers() != CRYPT_OK) { croak("FATAL: register_all_ciphers failed"); }
382 129 50         if(register_all_hashes() != CRYPT_OK) { croak("FATAL: register_all_hashes failed"); }
383 129 50         if(register_all_prngs() != CRYPT_OK) { croak("FATAL: register_all_prngs failed"); }
384 129 50         if(crypt_mp_init("ltm") != CRYPT_OK) { croak("FATAL: crypt_mp_init failed"); }
385              
386             SV *
387             CryptX__ltc_build_settings()
388             CODE:
389 1           RETVAL = newSVpv(crypt_build_settings, 0);
390             OUTPUT:
391             RETVAL
392              
393             SV *
394             CryptX__ltc_mp_name()
395             CODE:
396 1           RETVAL = newSVpv(ltc_mp.name, 0);
397             OUTPUT:
398             RETVAL
399              
400             int
401             CryptX__ltc_mp_bits_per_digit()
402             CODE:
403 1           RETVAL = ltc_mp.bits_per_digit;
404             OUTPUT:
405             RETVAL
406              
407             MODULE = CryptX PACKAGE = Crypt::Misc
408              
409             PROTOTYPES: DISABLE
410              
411             SV *
412             _radix_to_bin(char *in, int radix)
413             CODE:
414             {
415             STRLEN len;
416             unsigned char *out_data;
417             mp_int mpi;
418              
419 265 50         if (in == NULL) XSRETURN_UNDEF;
420 265 50         if (mp_init(&mpi) != MP_OKAY) XSRETURN_UNDEF;
421 265 50         if (strlen(in) == 0) {
422 0           RETVAL = newSVpvn("", 0);
423             }
424 265 50         else if (mp_read_radix(&mpi, in, radix) == CRYPT_OK) {
425 265           len = mp_unsigned_bin_size(&mpi);
426 265 50         if (len == 0) {
427 0           RETVAL = newSVpvn("", 0);
428             }
429             else {
430 265           RETVAL = NEWSV(0, len); /* avoid zero! */
431 265           SvPOK_only(RETVAL);
432 265           SvCUR_set(RETVAL, len);
433 265           out_data = (unsigned char *)SvPVX(RETVAL);
434 265 50         if (mp_to_unsigned_bin(&mpi, out_data) != MP_OKAY) {
435 0           SvREFCNT_dec(RETVAL);
436 265           RETVAL = newSVpvn(NULL, 0); /* undef */
437             }
438             }
439             }
440             else {
441 0           RETVAL = newSVpvn(NULL, 0); /* undef */
442             }
443 265           mp_clear(&mpi);
444             }
445             OUTPUT:
446             RETVAL
447              
448             SV *
449             _bin_to_radix(SV *in, int radix)
450             CODE:
451             {
452             STRLEN len;
453             unsigned char *in_data;
454             char *out_data;
455             mp_int mpi, tmp;
456             mp_digit d;
457             mp_err merr;
458 290           int digits = 0;
459              
460 290 50         if (!SvPOK(in) || radix < 2 || radix > 64) XSRETURN_UNDEF;
    50          
    50          
461 290 50         in_data = (unsigned char *) SvPVbyte(in, len);
462 290 50         if (mp_init_multi(&mpi, &tmp, NULL) != MP_OKAY) XSRETURN_UNDEF;
463 290 50         if (len == 0) {
464 0           RETVAL = newSVpvn("", 0);
465             }
466             else {
467 290 50         if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) {
468 290           merr = mp_copy(&mpi, &tmp);
469 5655 50         while (merr == MP_OKAY && mp_iszero(&tmp) == MP_NO) {
    100          
470 5365           merr = mp_div_d(&tmp, (mp_digit)radix, &tmp, &d);
471 5365           digits++;
472             }
473 290 50         if (merr != MP_OKAY) {
474 0           RETVAL = newSVpvn(NULL, 0); /* undef */
475             }
476 290 100         else if (digits == 0) {
477 25           RETVAL = newSVpvn("", 0);
478             }
479             else {
480 265           RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */
481 265           SvPOK_only(RETVAL);
482 265           out_data = SvPVX(RETVAL);
483 265 50         if (mp_toradix(&mpi, out_data, radix) == MP_OKAY) {
484 265           SvCUR_set(RETVAL, strlen(out_data));
485             }
486             else {
487 0           SvREFCNT_dec(RETVAL);
488 290           RETVAL = newSVpvn(NULL, 0); /* undef */
489             }
490             }
491             }
492             else {
493 0           RETVAL = newSVpvn(NULL, 0); /* undef */
494             }
495             }
496 290           mp_clear_multi(&tmp, &mpi, NULL);
497             }
498             OUTPUT:
499             RETVAL
500              
501             SV *
502             encode_b64(SV * in)
503             ALIAS:
504             encode_b64u = 1
505             CODE:
506             {
507             int rv;
508             STRLEN in_len;
509             unsigned long out_len;
510             unsigned char *in_data;
511             char *out_data;
512              
513 137 50         if (!SvPOK(in)) XSRETURN_UNDEF;
514 137 50         in_data = (unsigned char *) SvPVbyte(in, in_len);
515 137 50         if (in_len == 0) {
516 0           RETVAL = newSVpvn("", 0);
517             }
518             else {
519 137           out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1);
520 137           RETVAL = NEWSV(0, out_len); /* avoid zero! */
521 137           SvPOK_only(RETVAL);
522 137           out_data = SvPVX(RETVAL);
523 137 100         if (ix == 1)
524 59           rv = base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len);
525             else
526 78           rv = base64_encode(in_data, (unsigned long)in_len, out_data, &out_len);
527 137 50         if (rv != CRYPT_OK) {
528 0           SvREFCNT_dec(RETVAL);
529 0           XSRETURN_UNDEF;
530             }
531 137           SvCUR_set(RETVAL, out_len);
532             }
533             }
534             OUTPUT:
535             RETVAL
536              
537             SV *
538             decode_b64(SV * in)
539             ALIAS:
540             decode_b64u = 1
541             CODE:
542             {
543             int rv;
544             STRLEN in_len;
545             unsigned long out_len;
546             unsigned char *out_data;
547             char *in_data;
548              
549 486 50         if (!SvPOK(in)) XSRETURN_UNDEF;
550 486 50         in_data = SvPVbyte(in, in_len);
551 486 50         if (in_len == 0) {
552 0           RETVAL = newSVpvn("", 0);
553             }
554             else {
555 486           out_len = (unsigned long)in_len;
556 486           RETVAL = NEWSV(0, out_len); /* avoid zero! */
557 486           SvPOK_only(RETVAL);
558 486           out_data = (unsigned char *)SvPVX(RETVAL);
559 486 100         if (ix == 1)
560 76           rv = base64url_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len);
561             else
562 410           rv = base64_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len);
563 486 50         if (rv != CRYPT_OK) {
564 0           SvREFCNT_dec(RETVAL);
565 0           XSRETURN_UNDEF;
566             }
567 486           SvCUR_set(RETVAL, out_len);
568             }
569             }
570             OUTPUT:
571             RETVAL
572              
573             SV *
574             encode_b32r(SV *in)
575             ALIAS:
576             encode_b32b = 1
577             encode_b32z = 2
578             encode_b32c = 3
579             CODE:
580             {
581             STRLEN in_len;
582             unsigned long out_len;
583             unsigned char *in_data;
584             char *out_data;
585 232           int id = -1, err;
586              
587 232 50         if (!SvPOK(in)) XSRETURN_UNDEF;
588 232 100         if (ix == 0) id = BASE32_RFC4648;
589 232 100         if (ix == 1) id = BASE32_BASE32HEX;
590 232 100         if (ix == 2) id = BASE32_ZBASE32;
591 232 100         if (ix == 3) id = BASE32_CROCKFORD;
592 232 50         if (id == -1) XSRETURN_UNDEF;
593 232 50         in_data = (unsigned char *) SvPVbyte(in, in_len);
594 232 50         if (in_len == 0) {
595 0           RETVAL = newSVpvn("", 0);
596             }
597             else {
598 232           out_len = (unsigned long)((8 * in_len + 4) / 5 + 1);
599 232           RETVAL = NEWSV(0, out_len); /* avoid zero! */
600 232           SvPOK_only(RETVAL);
601 232           out_data = SvPVX(RETVAL);
602 232           err = base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id);
603 232 50         if (err != CRYPT_OK) {
604 0           SvREFCNT_dec(RETVAL);
605 0           XSRETURN_UNDEF;
606             }
607 232           SvCUR_set(RETVAL, out_len);
608             }
609             }
610             OUTPUT:
611             RETVAL
612              
613             SV *
614             decode_b32r(SV *in)
615             ALIAS:
616             decode_b32b = 1
617             decode_b32z = 2
618             decode_b32c = 3
619             CODE:
620             {
621             STRLEN in_len;
622             unsigned long out_len;
623             unsigned char *out_data;
624             char *in_data;
625 232           int id = -1, err;
626              
627 232 50         if (!SvPOK(in)) XSRETURN_UNDEF;
628 232 100         if (ix == 0) id = BASE32_RFC4648;
629 232 100         if (ix == 1) id = BASE32_BASE32HEX;
630 232 100         if (ix == 2) id = BASE32_ZBASE32;
631 232 100         if (ix == 3) id = BASE32_CROCKFORD;
632 232 50         if (id == -1) XSRETURN_UNDEF;
633 232 50         in_data = SvPVbyte(in, in_len);
634 232 50         if (in_len == 0) {
635 0           RETVAL = newSVpvn("", 0);
636             }
637             else {
638 232           out_len = (unsigned long)in_len;
639 232           RETVAL = NEWSV(0, out_len); /* avoid zero! */
640 232           SvPOK_only(RETVAL);
641 232           out_data = (unsigned char *)SvPVX(RETVAL);
642 232           err = base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id);
643 232 50         if (err != CRYPT_OK) {
644 0           SvREFCNT_dec(RETVAL);
645 0           XSRETURN_UNDEF;
646             }
647 232           SvCUR_set(RETVAL, out_len);
648             }
649             }
650             OUTPUT:
651             RETVAL
652              
653             SV *
654             increment_octets_le(SV * in)
655             CODE:
656             {
657 0           STRLEN len, i = 0;
658             unsigned char *out_data, *in_data;
659              
660 0 0         if (!SvPOK(in)) XSRETURN_UNDEF;
661 0 0         in_data = (unsigned char *)SvPVbyte(in, len);
662 0 0         if (len == 0) {
663 0           RETVAL = newSVpvn("", 0);
664             }
665             else {
666 0           RETVAL = NEWSV(0, len); /* avoid zero! */
667 0           SvPOK_only(RETVAL);
668 0           SvCUR_set(RETVAL, len);
669 0           out_data = (unsigned char *)SvPVX(RETVAL);
670 0           Copy(in_data, out_data, len, unsigned char);
671 0 0         while (i < len) {
672 0           out_data[i]++;
673 0 0         if (0 != out_data[i]) break;
674 0           i++;
675             }
676 0 0         if (i == len) {
677 0           SvREFCNT_dec(RETVAL);
678 0           croak("FATAL: increment_octets_le overflow");
679             }
680             }
681             }
682             OUTPUT:
683             RETVAL
684              
685             SV *
686             increment_octets_be(SV * in)
687             CODE:
688             {
689 0           STRLEN len, i = 0;
690             unsigned char *out_data, *in_data;
691              
692 0 0         if (!SvPOK(in)) XSRETURN_UNDEF;
693 0 0         in_data = (unsigned char *)SvPVbyte(in, len);
694 0 0         if (len == 0) {
695 0           RETVAL = newSVpvn("", 0);
696             }
697             else {
698 0           RETVAL = NEWSV(0, len); /* avoid zero! */
699 0           SvPOK_only(RETVAL);
700 0           SvCUR_set(RETVAL, len);
701 0           out_data = (unsigned char *)SvPVX(RETVAL);
702 0           Copy(in_data, out_data, len, unsigned char);
703 0 0         while (i < len) {
704 0           out_data[len - 1 - i]++;
705 0 0         if (0 != out_data[len - 1 - i]) break;
706 0           i++;
707             }
708 0 0         if (i == len) {
709 0           SvREFCNT_dec(RETVAL);
710 0           croak("FATAL: increment_octets_be overflow");
711             }
712             }
713             }
714             OUTPUT:
715             RETVAL
716              
717             ###############################################################################
718              
719             INCLUDE: inc/CryptX_Digest.xs.inc
720             INCLUDE: inc/CryptX_Digest_SHAKE.xs.inc
721             INCLUDE: inc/CryptX_Cipher.xs.inc
722              
723             INCLUDE: inc/CryptX_Checksum_Adler32.xs.inc
724             INCLUDE: inc/CryptX_Checksum_CRC32.xs.inc
725              
726             INCLUDE: inc/CryptX_AuthEnc_EAX.xs.inc
727             INCLUDE: inc/CryptX_AuthEnc_GCM.xs.inc
728             INCLUDE: inc/CryptX_AuthEnc_OCB.xs.inc
729             INCLUDE: inc/CryptX_AuthEnc_CCM.xs.inc
730             INCLUDE: inc/CryptX_AuthEnc_ChaCha20Poly1305.xs.inc
731              
732             INCLUDE: inc/CryptX_Stream_ChaCha.xs.inc
733             INCLUDE: inc/CryptX_Stream_Salsa20.xs.inc
734             INCLUDE: inc/CryptX_Stream_RC4.xs.inc
735             INCLUDE: inc/CryptX_Stream_Sober128.xs.inc
736             INCLUDE: inc/CryptX_Stream_Sosemanuk.xs.inc
737             INCLUDE: inc/CryptX_Stream_Rabbit.xs.inc
738              
739             INCLUDE: inc/CryptX_Mac_F9.xs.inc
740             INCLUDE: inc/CryptX_Mac_HMAC.xs.inc
741             INCLUDE: inc/CryptX_Mac_OMAC.xs.inc
742             INCLUDE: inc/CryptX_Mac_Pelican.xs.inc
743             INCLUDE: inc/CryptX_Mac_PMAC.xs.inc
744             INCLUDE: inc/CryptX_Mac_XCBC.xs.inc
745             INCLUDE: inc/CryptX_Mac_Poly1305.xs.inc
746             INCLUDE: inc/CryptX_Mac_BLAKE2s.xs.inc
747             INCLUDE: inc/CryptX_Mac_BLAKE2b.xs.inc
748              
749             INCLUDE: inc/CryptX_Mode_CBC.xs.inc
750             INCLUDE: inc/CryptX_Mode_ECB.xs.inc
751             INCLUDE: inc/CryptX_Mode_CFB.xs.inc
752             INCLUDE: inc/CryptX_Mode_OFB.xs.inc
753             INCLUDE: inc/CryptX_Mode_CTR.xs.inc
754             #INCLUDE: inc/CryptX_Mode_F8.xs.inc
755             #INCLUDE: inc/CryptX_Mode_LRW.xs.inc
756             #INCLUDE: inc/CryptX_Mode_XTS.xs.inc
757              
758             INCLUDE: inc/CryptX_PRNG.xs.inc
759              
760             INCLUDE: inc/CryptX_PK_RSA.xs.inc
761             INCLUDE: inc/CryptX_PK_DSA.xs.inc
762             INCLUDE: inc/CryptX_PK_DH.xs.inc
763             INCLUDE: inc/CryptX_PK_ECC.xs.inc
764             INCLUDE: inc/CryptX_PK_Ed25519.xs.inc
765             INCLUDE: inc/CryptX_PK_X25519.xs.inc
766              
767             INCLUDE: inc/CryptX_KeyDerivation.xs.inc
768              
769             INCLUDE: inc/CryptX_BigInt_LTM.xs.inc