Codebase list libcryptx-perl / 2c9995f
base32_encode + base32_decode from ltc Karel Miko 6 years ago
5 changed file(s) with 82 addition(s) and 166 deletion(s). Raw diff Collapse all Expand all
413413 RETVAL
414414
415415 SV *
416 CryptX__encode_b32(SV *in, unsigned idx)
417 CODE:
418 {
419 STRLEN in_len;
420 unsigned long out_len;
421 unsigned char *out_data, *in_data;
422 int rv, id = -1;
423
424 if (!SvPOK(in)) XSRETURN_UNDEF;
425 if (idx == 0) id = BASE32_RFC4648;
426 if (idx == 1) id = BASE32_BASE32HEX;
427 if (idx == 2) id = BASE32_ZBASE32;
428 if (idx == 3) id = BASE32_CROCKFORD;
429 if (id == -1) XSRETURN_UNDEF;
430 in_data = (unsigned char *) SvPVbyte(in, in_len);
431 out_len = (unsigned long)((8 * in_len + 4) / 5);
432 Newz(0, out_data, out_len, unsigned char);
433 if (!out_data) croak("FATAL: Newz failed [%ld]", out_len);
434 rv = base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id);
435 RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0);
436 Safefree(out_data);
437 }
438 OUTPUT:
439 RETVAL
440
441 SV *
442 CryptX__decode_b32(SV *in, unsigned idx)
443 CODE:
444 {
445 STRLEN in_len;
446 unsigned long out_len;
447 unsigned char *out_data, *in_data;
448 int rv, id = -1;
449
450 if (!SvPOK(in)) XSRETURN_UNDEF;
451 if (idx == 0) id = BASE32_RFC4648;
452 if (idx == 1) id = BASE32_BASE32HEX;
453 if (idx == 2) id = BASE32_ZBASE32;
454 if (idx == 3) id = BASE32_CROCKFORD;
455 if (id == -1) XSRETURN_UNDEF;
456 in_data = (unsigned char *) SvPVbyte(in, in_len);
457 out_len = (unsigned long)in_len;
458 Newz(0, out_data, out_len, unsigned char);
459 if (!out_data) croak("FATAL: Newz failed [%ld]", out_len);
460 rv = base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id);
461 RETVAL = (rv == CRYPT_OK) ? newSVpvn((char *)out_data, out_len) : newSVpvn(NULL, 0);
462 Safefree(out_data);
463 }
464 OUTPUT:
465 RETVAL
466
467 SV *
416468 CryptX__increment_octets_le(SV * in)
417469 CODE:
418470 {
531583 RETVAL
532584
533585 SV *
534 CryptX__encode_b32(SV *bytes, unsigned idx)
535 CODE:
536 {
537 STRLEN inlen, outlen, i, leven;
538 unsigned char *out, *in, *codes;
539 char *alphabet[] = {
540 "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", /* rfc4648 */
541 "0123456789ABCDEFGHIJKLMNOPQRSTUV", /* base32hex */
542 "ybndrfg8ejkmcpqxot1uwisza345h769", /* zbase32 */
543 "0123456789ABCDEFGHJKMNPQRSTVWXYZ" /* crockford */
544 };
545
546 if (!SvOK(bytes)) {
547 /* for undefined input return "" (empty string) */
548 RETVAL = newSVpv("", 0);
549 }
550 else {
551 if (!SvPOK(bytes) || idx > 3) XSRETURN_UNDEF; /* error */
552 in = (unsigned char *) SvPVbyte(bytes, inlen);
553 if (in == NULL) XSRETURN_UNDEF; /* error */
554 if (inlen == 0) {
555 RETVAL = newSVpv("", 0);
556 }
557 else {
558 codes = (unsigned char*)alphabet[idx];
559 outlen = (8 * inlen + 4) / 5;
560 RETVAL = NEWSV(0, outlen);
561 SvPOK_only(RETVAL);
562 SvCUR_set(RETVAL, outlen);
563 out = (unsigned char *)SvPV_nolen(RETVAL);
564
565 leven = 5 * (inlen / 5);
566 for (i = 0; i < leven; i += 5) {
567 *out++ = codes[(in[0] >> 3) & 0x1F];
568 *out++ = codes[(((in[0] & 0x7) << 2) + (in[1] >> 6)) & 0x1F];
569 *out++ = codes[(in[1] >> 1) & 0x1F];
570 *out++ = codes[(((in[1] & 0x1) << 4) + (in[2] >> 4)) & 0x1F];
571 *out++ = codes[(((in[2] & 0xF) << 1) + (in[3] >> 7)) & 0x1F];
572 *out++ = codes[(in[3] >> 2) & 0x1F];
573 *out++ = codes[(((in[3] & 0x3) << 3) + (in[4] >> 5)) & 0x1F];
574 *out++ = codes[in[4] & 0x1F];
575 in += 5;
576 }
577 if (i < inlen) {
578 unsigned a = in[0];
579 unsigned b = (i+1 < inlen) ? in[1] : 0;
580 unsigned c = (i+2 < inlen) ? in[2] : 0;
581 unsigned d = (i+3 < inlen) ? in[3] : 0;
582 *out++ = codes[(a >> 3) & 0x1F];
583 *out++ = codes[(((a & 0x7) << 2) + (b >> 6)) & 0x1F];
584 if (i+1 < inlen) {
585 *out++ = codes[(b >> 1) & 0x1F];
586 *out++ = codes[(((b & 0x1) << 4) + (c >> 4)) & 0x1F];
587 }
588 if (i+2 < inlen) {
589 *out++ = codes[(((c & 0xF) << 1) + (d >> 7)) & 0x1F];
590 *out++ = codes[(d >> 2) & 0x1F];
591 }
592 if (i+3 < inlen) {
593 *out++ = codes[((d & 0x3) << 3) & 0x1F];
594 }
595 }
596 }
597 }
598 }
599 OUTPUT:
600 RETVAL
601
602 SV *
603 CryptX__decode_b32(SV *base32, unsigned idx)
604 CODE:
605 {
606 STRLEN x, inlen, outlen;
607 int y = 0;
608 ulong64 t = 0;
609 unsigned char c, *in, *out, *map;
610 unsigned char tables[4][43] = {
611 { /* rfc4648 ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 */
612 99/*0*/,99/*1*/,26/*2*/,27/*3*/,28/*4*/,29/*5*/,30/*6*/,31/*7*/,99/*8*/,99/*9*/,
613 99/*:*/,99/*;*/,99/*<*/,99/*=*/,99/*>*/,99/*?*/,99/*@*/,
614 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/, 7/*H*/, 8/*I*/, 9/*J*/,10/*K*/,11/*L*/,12/*M*/,
615 13/*N*/,14/*O*/,15/*P*/,16/*Q*/,17/*R*/,18/*S*/,19/*T*/,20/*U*/,21/*V*/,22/*W*/,23/*X*/,24/*Y*/,25/*Z*/
616 },
617 { /* base32hex 0123456789ABCDEFGHIJKLMNOPQRSTUV */
618 0/*0*/, 1/*1*/, 2/*2*/, 3/*3*/, 4/*4*/, 5/*5*/, 6/*6*/, 7/*7*/, 8/*8*/, 9/*9*/,
619 99/*:*/,99/*;*/,99/*<*/,99/*=*/,99/*>*/,99/*?*/,99/*@*/,
620 10/*A*/,11/*B*/,12/*C*/,13/*D*/,14/*E*/,15/*F*/,16/*G*/,17/*H*/,18/*I*/,19/*J*/,20/*K*/,21/*L*/,22/*M*/,
621 23/*N*/,24/*O*/,25/*P*/,26/*Q*/,27/*R*/,28/*S*/,29/*T*/,30/*U*/,31/*V*/,99/*W*/,99/*X*/,99/*Y*/,99/*Z*/
622 },
623 { /* zbase32 YBNDRFG8EJKMCPQXOT1UWISZA345H769 */
624 99/*0*/,18/*1*/,99/*2*/,25/*3*/,26/*4*/,27/*5*/,30/*6*/,29/*7*/, 7/*8*/,31/*9*/,
625 99/*:*/,99/*;*/,99/*<*/,99/*=*/,99/*>*/,99/*?*/,99/*@*/,
626 24/*A*/, 1/*B*/,12/*C*/, 3/*D*/, 8/*E*/, 5/*F*/, 6/*G*/,28/*H*/,21/*I*/, 9/*J*/,10/*K*/,99/*L*/,11/*M*/,
627 2/*N*/,16/*O*/,13/*P*/,14/*Q*/, 4/*R*/,22/*S*/,17/*T*/,19/*U*/,99/*V*/,20/*W*/,15/*X*/, 0/*Y*/,23/*Z*/
628 },
629 { /* crockford 0123456789ABCDEFGHJKMNPQRSTVWXYZ + O=>0 + IL=>1 */
630 0/*0*/, 1/*1*/, 2/*2*/, 3/*3*/, 4/*4*/, 5/*5*/, 6/*6*/, 7/*7*/, 8/*8*/, 9/*9*/,
631 99/*:*/,99/*;*/,99/*<*/,99/*=*/,99/*>*/,99/*?*/,99/*@*/,
632 10/*A*/,11/*B*/,12/*C*/,13/*D*/,14/*E*/,15/*F*/,16/*G*/,17/*H*/, 1/*I*/,18/*J*/,19/*K*/, 1/*L*/,20/*M*/,
633 21/*N*/, 0/*O*/,22/*P*/,23/*Q*/,24/*R*/,25/*S*/,26/*T*/,99/*U*/,27/*V*/,28/*W*/,29/*X*/,30/*Y*/,31/*Z*/
634 }
635 };
636
637 if (!SvOK(base32)) {
638 /* for undefined input return "" (empty string) */
639 RETVAL = newSVpv("", 0);
640 }
641 else {
642 if (!SvPOK(base32) || idx > 3) XSRETURN_UNDEF; /* error */
643 in = (unsigned char *) SvPVbyte(base32, inlen);
644 if (in == NULL) XSRETURN_UNDEF; /* error */
645
646 while (inlen>0 && in[inlen-1] == '=') inlen--;
647 if (inlen == 0) {
648 RETVAL = newSVpv("", 0);
649 }
650 else {
651 x = inlen % 8;
652 if (x == 1 || x == 3 || x == 6) XSRETURN_UNDEF; /* error */
653 outlen = (inlen * 5) / 8;
654 RETVAL = NEWSV(0, outlen);
655 SvPOK_only(RETVAL);
656 SvCUR_set(RETVAL, outlen);
657 out = (unsigned char *)SvPV_nolen(RETVAL);
658 map = tables[idx];
659 for (x = 0; x < inlen; x++) {
660 c = in[x];
661 /* convert to upper case */
662 if ((c >= 'a') && (c <= 'z')) c -= 32;
663 /* '0' = 48 .. 'Z' = 90 */
664 if (c < 48 || c > 90 || map[c-48] > 31) XSRETURN_UNDEF; /* error */
665 t = (t<<5)|map[c-48];
666 if (++y == 8) {
667 *out++ = (unsigned char)((t>>32) & 255);
668 *out++ = (unsigned char)((t>>24) & 255);
669 *out++ = (unsigned char)((t>>16) & 255);
670 *out++ = (unsigned char)((t>> 8) & 255);
671 *out++ = (unsigned char)( t & 255);
672 y = 0;
673 t = 0;
674 }
675 }
676 if (y > 0) {
677 t = t << (5 * (8 - y));
678 if (y >= 2) *out++ = (unsigned char)((t>>32) & 255);
679 if (y >= 4) *out++ = (unsigned char)((t>>24) & 255);
680 if (y >= 5) *out++ = (unsigned char)((t>>16) & 255);
681 if (y >= 7) *out++ = (unsigned char)((t>> 8) & 255);
682 }
683 }
684 }
685 }
686 OUTPUT:
687 RETVAL
688
689 SV *
690586 CryptX__ltc_build_settings()
691587 CODE:
692588 RETVAL = newSVpv(crypt_build_settings, 0);
4141 ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \
4242 ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o \
4343 ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o ltc/misc/zeromem.o \
44 ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o \
45 ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o \
46 ltc/misc/crypt/crypt_constants.o ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o \
47 ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o \
48 ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o \
49 ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o \
50 ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o \
51 ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \
44 ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o \
45 ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \
46 ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o \
47 ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \
48 ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \
49 ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \
50 ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \
51 ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \
52 ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \
5253 ltc/misc/crypt/crypt_register_all_hashes.o ltc/misc/crypt/crypt_register_all_prngs.o \
5354 ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \
5455 ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \
4444 ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \
4545 ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/crc32.obj \
4646 ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj ltc/misc/zeromem.obj \
47 ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj \
48 ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \
47 ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj \
48 ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \
49 ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \
4950 ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \
5051 ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \
5152 ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \
443443 #define LTC_BASE64
444444 /* ... and it's URL safe version */
445445 #define LTC_BASE64_URL
446 /* Base32 encoding/decoding */
447 #define LTC_BASE32
446448
447449 /* Keep LTC_NO_HKDF for compatibility reasons
448450 * superseeded by LTC_NO_MISC*/
2727 unsigned char *out, unsigned long *outlen);
2828 int base64url_strict_decode(const unsigned char *in, unsigned long len,
2929 unsigned char *out, unsigned long *outlen);
30 #endif
31
32 /* ---- BASE32 Routines ---- */
33 #ifdef LTC_BASE32
34 typedef enum {
35 BASE32_RFC4648 = 0,
36 BASE32_BASE32HEX = 1,
37 BASE32_ZBASE32 = 2,
38 BASE32_CROCKFORD = 3
39 } base32_alphabet;
40 int base32_encode(const unsigned char *in, unsigned long inlen,
41 unsigned char *out, unsigned long *outlen,
42 base32_alphabet id);
43 int base32_decode(const unsigned char *in, unsigned long inlen,
44 unsigned char *out, unsigned long *outlen,
45 base32_alphabet id);
3046 #endif
3147
3248 /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */