moving more code to XS
Karel Miko
6 years ago
280 | 280 | return CRYPT_OK; |
281 | 281 | } |
282 | 282 | |
283 | int _find_start(const char *name, char *ltcname, size_t ltclen) | |
283 | size_t _find_start(const char *name, char *ltcname, size_t ltclen) | |
284 | 284 | { |
285 | 285 | size_t i, start = 0; |
286 | 286 | if (name == NULL || strlen(name) + 1 > ltclen) croak("FATAL: invalid name") ; |
432 | 432 | } |
433 | 433 | else { |
434 | 434 | out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); |
435 | RETVAL = NEWSV(0, out_len); | |
435 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
436 | 436 | SvPOK_only(RETVAL); |
437 | 437 | out_data = (unsigned char *)SvPVX(RETVAL); |
438 | 438 | if (base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { |
460 | 460 | } |
461 | 461 | else { |
462 | 462 | out_len = (unsigned long)in_len; |
463 | RETVAL = NEWSV(0, out_len); | |
463 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
464 | 464 | SvPOK_only(RETVAL); |
465 | 465 | out_data = (unsigned char *)SvPVX(RETVAL); |
466 | 466 | if (base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { |
488 | 488 | } |
489 | 489 | else { |
490 | 490 | out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1); |
491 | RETVAL = NEWSV(0, out_len); | |
491 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
492 | 492 | SvPOK_only(RETVAL); |
493 | 493 | out_data = (unsigned char *)SvPVX(RETVAL); |
494 | 494 | if (base64_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { |
516 | 516 | } |
517 | 517 | else { |
518 | 518 | out_len = (unsigned long)in_len; |
519 | RETVAL = NEWSV(0, out_len); | |
519 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
520 | 520 | SvPOK_only(RETVAL); |
521 | 521 | out_data = (unsigned char *)SvPVX(RETVAL); |
522 | 522 | if (base64_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) { |
550 | 550 | } |
551 | 551 | else { |
552 | 552 | out_len = (unsigned long)((8 * in_len + 4) / 5); |
553 | RETVAL = NEWSV(0, out_len); | |
553 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
554 | 554 | SvPOK_only(RETVAL); |
555 | 555 | out_data = (unsigned char *)SvPVX(RETVAL); |
556 | 556 | if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { |
584 | 584 | } |
585 | 585 | else { |
586 | 586 | out_len = (unsigned long)in_len; |
587 | RETVAL = NEWSV(0, out_len); | |
587 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
588 | 588 | SvPOK_only(RETVAL); |
589 | 589 | out_data = (unsigned char *)SvPVX(RETVAL); |
590 | 590 | if (base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { |
606 | 606 | |
607 | 607 | if (!SvPOK(in)) XSRETURN_UNDEF; |
608 | 608 | in_data = (unsigned char *)SvPVbyte(in, len); |
609 | if (len == 0) XSRETURN_UNDEF; | |
610 | ||
611 | RETVAL = NEWSV(0, len); | |
612 | SvPOK_only(RETVAL); | |
613 | SvCUR_set(RETVAL, len); | |
614 | out_data = (unsigned char *)SvPVX(RETVAL); | |
615 | Copy(in_data, out_data, len, unsigned char); | |
616 | while (i < len) { | |
617 | out_data[i]++; | |
618 | if (0 != out_data[i]) break; | |
619 | i++; | |
620 | } | |
621 | if (i == len) { | |
622 | SvREFCNT_dec(RETVAL); | |
623 | croak("FATAL: increment_octets_le overflow"); | |
609 | if (len == 0) { | |
610 | RETVAL = newSVpvn("", 0); | |
611 | } | |
612 | else { | |
613 | RETVAL = NEWSV(0, len); /* avoid zero! */ | |
614 | SvPOK_only(RETVAL); | |
615 | SvCUR_set(RETVAL, len); | |
616 | out_data = (unsigned char *)SvPVX(RETVAL); | |
617 | Copy(in_data, out_data, len, unsigned char); | |
618 | while (i < len) { | |
619 | out_data[i]++; | |
620 | if (0 != out_data[i]) break; | |
621 | i++; | |
622 | } | |
623 | if (i == len) { | |
624 | SvREFCNT_dec(RETVAL); | |
625 | croak("FATAL: increment_octets_le overflow"); | |
626 | } | |
624 | 627 | } |
625 | 628 | } |
626 | 629 | OUTPUT: |
635 | 638 | |
636 | 639 | if (!SvPOK(in)) XSRETURN_UNDEF; |
637 | 640 | in_data = (unsigned char *)SvPVbyte(in, len); |
638 | if (len == 0) XSRETURN_UNDEF; | |
639 | ||
640 | RETVAL = NEWSV(0, len); | |
641 | SvPOK_only(RETVAL); | |
642 | SvCUR_set(RETVAL, len); | |
643 | out_data = (unsigned char *)SvPVX(RETVAL); | |
644 | Copy(in_data, out_data, len, unsigned char); | |
645 | while (i < len) { | |
646 | out_data[len - 1 - i]++; | |
647 | if (0 != out_data[len - 1 - i]) break; | |
648 | i++; | |
649 | } | |
650 | if (i == len) { | |
651 | SvREFCNT_dec(RETVAL); | |
652 | croak("FATAL: increment_octets_be overflow"); | |
641 | if (len == 0) { | |
642 | RETVAL = newSVpvn("", 0); | |
643 | } | |
644 | else { | |
645 | RETVAL = NEWSV(0, len); /* avoid zero! */ | |
646 | SvPOK_only(RETVAL); | |
647 | SvCUR_set(RETVAL, len); | |
648 | out_data = (unsigned char *)SvPVX(RETVAL); | |
649 | Copy(in_data, out_data, len, unsigned char); | |
650 | while (i < len) { | |
651 | out_data[len - 1 - i]++; | |
652 | if (0 != out_data[len - 1 - i]) break; | |
653 | i++; | |
654 | } | |
655 | if (i == len) { | |
656 | SvREFCNT_dec(RETVAL); | |
657 | croak("FATAL: increment_octets_be overflow"); | |
658 | } | |
653 | 659 | } |
654 | 660 | } |
655 | 661 | OUTPUT: |
663 | 669 | unsigned char *out_data; |
664 | 670 | mp_int mpi; |
665 | 671 | |
666 | if (in == NULL || strlen(in) == 0) XSRETURN_UNDEF; | |
667 | if (mp_init(&mpi) != CRYPT_OK) XSRETURN_UNDEF; | |
668 | ||
669 | if (mp_read_radix(&mpi, in, radix) == CRYPT_OK) { | |
672 | if (in == NULL) XSRETURN_UNDEF; | |
673 | if (mp_init(&mpi) != CRYPT_OK) XSRETURN_UNDEF; | |
674 | if (strlen(in) == 0) { | |
675 | RETVAL = newSVpvn("", 0); | |
676 | } | |
677 | else if (mp_read_radix(&mpi, in, radix) == CRYPT_OK) { | |
670 | 678 | len = mp_unsigned_bin_size(&mpi); |
671 | RETVAL = NEWSV(0, len); | |
672 | SvPOK_only(RETVAL); | |
673 | SvCUR_set(RETVAL, len); | |
674 | out_data = (unsigned char *)SvPVX(RETVAL); | |
675 | mp_to_unsigned_bin(&mpi, out_data); | |
676 | mp_clear(&mpi); | |
677 | } | |
678 | else { | |
679 | XSRETURN_UNDEF; | |
680 | } | |
679 | if (len == 0) { | |
680 | RETVAL = newSVpvn("", 0); | |
681 | } | |
682 | else { | |
683 | RETVAL = NEWSV(0, len); /* avoid zero! */ | |
684 | SvPOK_only(RETVAL); | |
685 | SvCUR_set(RETVAL, len); | |
686 | out_data = (unsigned char *)SvPVX(RETVAL); | |
687 | mp_to_unsigned_bin(&mpi, out_data); | |
688 | } | |
689 | } | |
690 | else { | |
691 | RETVAL = newSVpvn(NULL, 0); /* undef */ | |
692 | } | |
693 | mp_clear(&mpi); | |
681 | 694 | } |
682 | 695 | OUTPUT: |
683 | 696 | RETVAL |
695 | 708 | |
696 | 709 | if (!SvPOK(in) || radix < 2 || radix > 64) XSRETURN_UNDEF; |
697 | 710 | in_data = (unsigned char *) SvPVbyte(in, len); |
698 | if (len == 0) XSRETURN_UNDEF; | |
699 | ||
700 | mp_init(&mpi); | |
701 | if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) { | |
702 | mp_init_copy(&tmp, &mpi); | |
703 | while (mp_iszero(&tmp) == MP_NO) { | |
704 | mp_div_d(&tmp, (mp_digit)radix, &tmp, &d); | |
705 | digits++; | |
706 | } | |
707 | mp_clear(&tmp); | |
708 | ||
709 | if (digits == 0) { | |
710 | RETVAL = newSVpvn("", 0); | |
711 | mp_clear(&mpi); | |
711 | mp_init_multi(&mpi, &tmp, NULL); | |
712 | if (len == 0) { | |
713 | RETVAL = newSVpvn("", 0); | |
714 | } | |
715 | else { | |
716 | if (mp_read_unsigned_bin(&mpi, in_data, (unsigned long)len) == CRYPT_OK) { | |
717 | mp_copy(&mpi, &tmp); | |
718 | while (mp_iszero(&tmp) == MP_NO) { | |
719 | mp_div_d(&tmp, (mp_digit)radix, &tmp, &d); | |
720 | digits++; | |
721 | } | |
722 | if (digits == 0) { | |
723 | RETVAL = newSVpvn("", 0); | |
724 | } | |
725 | else { | |
726 | RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */ | |
727 | SvPOK_only(RETVAL); | |
728 | out_data = SvPVX(RETVAL); | |
729 | mp_toradix(&mpi, out_data, radix); | |
730 | SvCUR_set(RETVAL, strlen(out_data)); | |
731 | } | |
712 | 732 | } |
713 | 733 | else { |
714 | RETVAL = NEWSV(0, digits + 2); /* +2 for sign and NUL byte */ | |
715 | SvPOK_only(RETVAL); | |
716 | out_data = SvPVX(RETVAL); | |
717 | mp_toradix(&mpi, out_data, radix); | |
718 | SvCUR_set(RETVAL, strlen(out_data)); | |
719 | mp_clear(&mpi); | |
720 | } | |
721 | } | |
722 | else { | |
723 | mp_clear(&mpi); | |
724 | XSRETURN_UNDEF; | |
725 | } | |
734 | RETVAL = newSVpvn(NULL, 0); /* undef */ | |
735 | } | |
736 | } | |
737 | mp_clear_multi(&tmp, &mpi, NULL); | |
726 | 738 | } |
727 | 739 | OUTPUT: |
728 | 740 | RETVAL |
30 | 30 | if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
31 | 31 | [%-END%] |
32 | 32 | |
33 | LTC_UNUSED_PARAM(class); | |
33 | 34 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
34 | 35 | k = (unsigned char *) SvPVbyte(key, k_len); |
35 | 36 | |
130 | 131 | RETVAL = newSVpvn(out, outlen); |
131 | 132 | } |
132 | 133 | else { |
133 | RETVAL = newSVpvn(mac, maclen); | |
134 | RETVAL = newSVpvn((char * )mac, maclen); | |
134 | 135 | } |
135 | 136 | } |
136 | 137 | OUTPUT: |
168 | 169 | [%-IF lc_name == 'hmac' %] |
169 | 170 | int id = _find_hash(hash_name); |
170 | 171 | if (id == -1) croak("FATAL: find_digest failed for '%s'", hash_name); |
171 | rv = [%lc_name%]_init(&st, id, k, klen); | |
172 | rv = [%lc_name%]_init(&st, id, k, (unsigned long)klen); | |
172 | 173 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv)); |
173 | 174 | for (i = 2; i < items; i++) { |
174 | 175 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
175 | 176 | if (inlen > 0) { |
176 | rv = [%lc_name%]_process(&st, in, inlen); | |
177 | rv = [%lc_name%]_process(&st, in, (unsigned long)inlen); | |
177 | 178 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv)); |
178 | 179 | } |
179 | 180 | } |
181 | 182 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv)); |
182 | 183 | [%-ELSIF lc_name == 'blake2s' || lc_name == 'blake2b' %] |
183 | 184 | if (size < len) len = size; |
184 | rv = [%lc_name%]mac_init(&st, len, k, klen); | |
185 | rv = [%lc_name%]mac_init(&st, len, k, (unsigned long)klen); | |
185 | 186 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_init failed: %s", error_to_string(rv)); |
186 | 187 | for (i = 2; i < items; i++) { |
187 | 188 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
188 | 189 | if (inlen > 0) { |
189 | rv = [%lc_name%]mac_process(&st, in, inlen); | |
190 | rv = [%lc_name%]mac_process(&st, in, (unsigned long)inlen); | |
190 | 191 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_process failed: %s", error_to_string(rv)); |
191 | 192 | } |
192 | 193 | } |
194 | 195 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_done failed: %s", error_to_string(rv)); |
195 | 196 | [%-ELSIF lc_name == 'pelican' %] |
196 | 197 | len = 16; |
197 | rv = [%lc_name%]_init(&st, k, klen); | |
198 | rv = [%lc_name%]_init(&st, k, (unsigned long)klen); | |
198 | 199 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv)); |
199 | 200 | for (i = 1; i < items; i++) { |
200 | 201 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
201 | 202 | if (inlen > 0) { |
202 | rv = [%lc_name%]_process(&st, in, inlen); | |
203 | rv = [%lc_name%]_process(&st, in, (unsigned long)inlen); | |
203 | 204 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv)); |
204 | 205 | } |
205 | 206 | } |
206 | 207 | rv = [%lc_name%]_done(&st, mac); |
207 | 208 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv)); |
208 | 209 | [%-ELSIF lc_name == 'poly1305' %] |
209 | rv = [%lc_name%]_init(&st, k, klen); | |
210 | rv = [%lc_name%]_init(&st, k, (unsigned long)klen); | |
210 | 211 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv)); |
211 | 212 | for (i = 1; i < items; i++) { |
212 | 213 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
213 | 214 | if (inlen > 0) { |
214 | rv = [%lc_name%]_process(&st, in, inlen); | |
215 | rv = [%lc_name%]_process(&st, in, (unsigned long)inlen); | |
215 | 216 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv)); |
216 | 217 | } |
217 | 218 | } |
220 | 221 | [%-ELSE%] |
221 | 222 | int id = _find_cipher(cipher_name); |
222 | 223 | if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); |
223 | rv = [%lc_name%]_init(&st, id, k, klen); | |
224 | rv = [%lc_name%]_init(&st, id, k, (unsigned long)klen); | |
224 | 225 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv)); |
225 | 226 | for (i = 2; i < items; i++) { |
226 | 227 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
227 | 228 | if (inlen > 0) { |
228 | rv = [%lc_name%]_process(&st, in, inlen); | |
229 | rv = [%lc_name%]_process(&st, in, (unsigned long)inlen); | |
229 | 230 | if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv)); |
230 | 231 | } |
231 | 232 | } |
9 | 9 | [%-END%] |
10 | 10 | CODE: |
11 | 11 | { |
12 | LTC_UNUSED_PARAM(class); | |
12 | 13 | Newz(0, RETVAL, 1, struct [%lc_name%]_struct); |
13 | 14 | if (!RETVAL) croak("FATAL: Newz failed"); |
14 | 15 | RETVAL->direction = 0; |
36 | 37 | |
37 | 38 | void |
38 | 39 | [%-IF lc_name == 'xts' %] |
39 | _start(_XXX_XXX_XXX_) | |
40 | start_decrypt(_XXX_XXX_XXX_) | |
40 | 41 | [%-ELSIF lc_name == 'f8' %] |
41 | _start(_XXX_XXX_XXX_) | |
42 | start_decrypt(_XXX_XXX_XXX_) | |
42 | 43 | [%-ELSIF lc_name == 'lrw' %] |
43 | _start(_XXX_XXX_XXX_) | |
44 | start_decrypt(_XXX_XXX_XXX_) | |
44 | 45 | [%-ELSE%] |
45 | _start(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv) | |
46 | start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv) | |
46 | 47 | [%-END%] |
47 | 48 | ALIAS: |
48 | 49 | start_encrypt = 1 |
49 | start_decrypt = 2 | |
50 | 50 | PPCODE: |
51 | 51 | { |
52 | 52 | STRLEN k_len=0; |
96 | 96 | RETVAL = newSVpvn("", 0); |
97 | 97 | } |
98 | 98 | else { |
99 | RETVAL = NEWSV(0, in_data_len); | |
99 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
100 | 100 | SvPOK_only(RETVAL); |
101 | 101 | SvCUR_set(RETVAL, in_data_len); |
102 | 102 | out_data = (unsigned char *)SvPVX(RETVAL); |
5 | 5 | new(char * class, char * cipher_name, int padding=1, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct [%lc_name%]_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->padding_mode = padding; |
27 | 28 | |
28 | 29 | void |
29 | 30 | [%-IF lc_name == 'cbc' %] |
30 | _start(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv) | |
31 | start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv) | |
31 | 32 | [%-ELSIF lc_name == 'ecb' %] |
32 | _start(Crypt::Mode::[%orig_name%] self, SV * key) | |
33 | start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key) | |
33 | 34 | [%-ELSE%] |
34 | _start(_XXX_XXX_XXX_) | |
35 | start_decrypt(_XXX_XXX_XXX_) | |
35 | 36 | [%-END%] |
36 | 37 | ALIAS: |
37 | 38 | start_encrypt = 1 |
38 | start_decrypt = 2 | |
39 | 39 | PPCODE: |
40 | 40 | { |
41 | 41 | int rv; |
113 | 113 | |
114 | 114 | if (in_data_len > 0) { |
115 | 115 | i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); |
116 | RETVAL = NEWSV(0, i); | |
116 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
117 | 117 | SvPOK_only(RETVAL); |
118 | 118 | SvCUR_set(RETVAL, i); |
119 | 119 | out_data = (unsigned char *)SvPVX(RETVAL); |
194 | 194 | RETVAL = newSVpvn("", 0); |
195 | 195 | } |
196 | 196 | else { |
197 | RETVAL = NEWSV(0, i); | |
197 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
198 | 198 | SvPOK_only(RETVAL); |
199 | 199 | SvCUR_set(RETVAL, i); |
200 | 200 | out_data = (unsigned char *)SvPVX(RETVAL); |
10 | 10 | unsigned char *h=NULL; |
11 | 11 | STRLEN h_len=0; |
12 | 12 | int rv, id; |
13 | LTC_UNUSED_PARAM(class); | |
13 | 14 | |
14 | 15 | if (tag_len < 1 || tag_len > MAXBLOCKSIZE) croak("FATAL: invalid tag_len %d", tag_len); |
15 | 16 | if (pt_len < 0) croak("FATAL: invalid pt_len"); |
80 | 81 | croak("FATAL: encrypt_add failed: wrong direction"); |
81 | 82 | } |
82 | 83 | if (self->pt_len < in_data_len) croak("FATAL: encrypt_add failed: pt_len mismatch"); |
83 | RETVAL = NEWSV(0, in_data_len); | |
84 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
84 | 85 | SvPOK_only(RETVAL); |
85 | 86 | SvCUR_set(RETVAL, in_data_len); |
86 | 87 | out_data = (unsigned char *)SvPVX(RETVAL); |
113 | 114 | croak("FATAL: decrypt_add failed: wrong direction"); |
114 | 115 | } |
115 | 116 | if (self->pt_len < in_data_len) croak("FATAL: decrypt_add failed: pt_len mismatch"); |
116 | RETVAL = NEWSV(0, in_data_len); | |
117 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
117 | 118 | SvPOK_only(RETVAL); |
118 | 119 | SvCUR_set(RETVAL, in_data_len); |
119 | 120 | out_data = (unsigned char *)SvPVX(RETVAL); |
178 | 179 | } |
179 | 180 | } |
180 | 181 | } |
182 | ||
183 | void | |
184 | ccm_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext) | |
185 | PPCODE: | |
186 | { | |
187 | STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; | |
188 | unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; | |
189 | int rv, id; | |
190 | unsigned char tag[MAXBLOCKSIZE]; | |
191 | SV *output; | |
192 | ||
193 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
194 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
195 | if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); | |
196 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
197 | ||
198 | id = _find_cipher(cipher_name); | |
199 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
200 | output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ | |
201 | SvPOK_only(output); | |
202 | SvCUR_set(output, pt_len); | |
203 | if(tag_len < 4 || tag_len > 16) tag_len = 16; | |
204 | ||
205 | rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
206 | pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, CCM_ENCRYPT); | |
207 | ||
208 | if (rv != CRYPT_OK) { | |
209 | SvREFCNT_dec(output); | |
210 | croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); | |
211 | } | |
212 | XPUSHs(sv_2mortal(output)); | |
213 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); | |
214 | } | |
215 | ||
216 | void | |
217 | ccm_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) | |
218 | PPCODE: | |
219 | { | |
220 | STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; | |
221 | unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; | |
222 | int rv, id; | |
223 | unsigned char tag[MAXBLOCKSIZE]; | |
224 | unsigned long tag_len; | |
225 | SV *output; | |
226 | ||
227 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
228 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
229 | if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); | |
230 | if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); | |
231 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
232 | ||
233 | id = _find_cipher(cipher_name); | |
234 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
235 | output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ | |
236 | SvPOK_only(output); | |
237 | SvCUR_set(output, ct_len); | |
238 | tag_len = (unsigned long)t_len; | |
239 | Copy(t, tag, t_len, unsigned char); | |
240 | ||
241 | rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
242 | (unsigned char *)SvPVX(output), (unsigned long)ct_len, ct, tag, &tag_len, CCM_DECRYPT); | |
243 | ||
244 | if (rv != CRYPT_OK) { | |
245 | SvREFCNT_dec(output); | |
246 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ | |
247 | } | |
248 | else { | |
249 | XPUSHs(sv_2mortal(output)); | |
250 | } | |
251 | } |
6 | 6 | int rv; |
7 | 7 | STRLEN iv_len=0, k_len=0; |
8 | 8 | unsigned char *iv=NULL, *k=NULL; |
9 | LTC_UNUSED_PARAM(class); | |
9 | 10 | |
10 | 11 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
11 | 12 | k = (unsigned char *) SvPVbyte(key, k_len); |
105 | 106 | RETVAL = newSVpvn("", 0); |
106 | 107 | } |
107 | 108 | else { |
108 | RETVAL = NEWSV(0, in_data_len); | |
109 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
109 | 110 | SvPOK_only(RETVAL); |
110 | 111 | SvCUR_set(RETVAL, in_data_len); |
111 | 112 | out_data = (unsigned char *)SvPVX(RETVAL); |
132 | 133 | RETVAL = newSVpvn("", 0); |
133 | 134 | } |
134 | 135 | else { |
135 | RETVAL = NEWSV(0, in_data_len); | |
136 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
136 | 137 | SvPOK_only(RETVAL); |
137 | 138 | SvCUR_set(RETVAL, in_data_len); |
138 | 139 | out_data = (unsigned char *)SvPVX(RETVAL); |
188 | 189 | } |
189 | 190 | } |
190 | 191 | } |
192 | ||
193 | void | |
194 | chacha20poly1305_encrypt_authenticate(SV *key, SV *nonce, SV *header, SV *plaintext) | |
195 | PPCODE: | |
196 | { | |
197 | STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; | |
198 | unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; | |
199 | int rv; | |
200 | unsigned char tag[MAXBLOCKSIZE]; | |
201 | unsigned long tag_len = sizeof(tag); | |
202 | SV *output; | |
203 | ||
204 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
205 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
206 | if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); | |
207 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
208 | ||
209 | output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ | |
210 | SvPOK_only(output); | |
211 | SvCUR_set(output, pt_len); | |
212 | ||
213 | rv = chacha20poly1305_memory(k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
214 | pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, | |
215 | CHACHA20POLY1305_ENCRYPT); | |
216 | ||
217 | if (rv != CRYPT_OK) { | |
218 | SvREFCNT_dec(output); | |
219 | croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); | |
220 | } | |
221 | XPUSHs(sv_2mortal(output)); | |
222 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); | |
223 | } | |
224 | ||
225 | void | |
226 | chacha20poly1305_decrypt_verify(SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) | |
227 | PPCODE: | |
228 | { | |
229 | STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; | |
230 | unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; | |
231 | int rv; | |
232 | unsigned char tag[MAXBLOCKSIZE]; | |
233 | unsigned long tag_len; | |
234 | SV *output; | |
235 | ||
236 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
237 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
238 | if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); | |
239 | if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); | |
240 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
241 | ||
242 | output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ | |
243 | SvPOK_only(output); | |
244 | SvCUR_set(output, ct_len); | |
245 | tag_len = (unsigned long)t_len; | |
246 | Copy(t, tag, t_len, unsigned char); | |
247 | ||
248 | rv = chacha20poly1305_memory(k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
249 | ct, (unsigned long)ct_len, (unsigned char *)SvPVX(output), tag, &tag_len, | |
250 | CHACHA20POLY1305_DECRYPT); | |
251 | ||
252 | if (rv != CRYPT_OK) { | |
253 | SvREFCNT_dec(output); | |
254 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ | |
255 | } | |
256 | else { | |
257 | XPUSHs(sv_2mortal(output)); | |
258 | } | |
259 | } |
10 | 10 | unsigned char *h=NULL; |
11 | 11 | STRLEN h_len=0; |
12 | 12 | int rv, id; |
13 | LTC_UNUSED_PARAM(class); | |
13 | 14 | |
14 | 15 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
15 | 16 | k = (unsigned char *) SvPVbyte(key, k_len); |
62 | 63 | RETVAL = newSVpvn("", 0); |
63 | 64 | } |
64 | 65 | else { |
65 | RETVAL = NEWSV(0, in_data_len); | |
66 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
66 | 67 | SvPOK_only(RETVAL); |
67 | 68 | SvCUR_set(RETVAL, in_data_len); |
68 | 69 | out_data = (unsigned char *)SvPVX(RETVAL); |
89 | 90 | RETVAL = newSVpvn("", 0); |
90 | 91 | } |
91 | 92 | else { |
92 | RETVAL = NEWSV(0, in_data_len); | |
93 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
93 | 94 | SvPOK_only(RETVAL); |
94 | 95 | SvCUR_set(RETVAL, in_data_len); |
95 | 96 | out_data = (unsigned char *)SvPVX(RETVAL); |
158 | 159 | if (rv != CRYPT_OK) croak("FATAL: eax_addheader failed: %s", error_to_string(rv)); |
159 | 160 | XPUSHs(ST(0)); /* return self */ |
160 | 161 | } |
162 | ||
163 | void | |
164 | eax_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, SV *plaintext) | |
165 | PPCODE: | |
166 | { | |
167 | STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; | |
168 | unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; | |
169 | int rv, id; | |
170 | unsigned char tag[MAXBLOCKSIZE]; | |
171 | unsigned long tag_len = sizeof(tag); | |
172 | SV *output; | |
173 | ||
174 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
175 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
176 | if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); | |
177 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
178 | ||
179 | id = _find_cipher(cipher_name); | |
180 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
181 | output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ | |
182 | SvPOK_only(output); | |
183 | SvCUR_set(output, pt_len); | |
184 | ||
185 | rv = eax_encrypt_authenticate_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, | |
186 | h, (unsigned long)h_len, pt, (unsigned long)pt_len, | |
187 | (unsigned char *)SvPVX(output), tag, &tag_len); | |
188 | ||
189 | if (rv != CRYPT_OK) { | |
190 | SvREFCNT_dec(output); | |
191 | croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); | |
192 | } | |
193 | XPUSHs(sv_2mortal(output)); | |
194 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); | |
195 | } | |
196 | ||
197 | void | |
198 | eax_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) | |
199 | PPCODE: | |
200 | { | |
201 | STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; | |
202 | unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; | |
203 | int rv, id, stat = 0; | |
204 | unsigned char tag[MAXBLOCKSIZE]; | |
205 | unsigned long tag_len; | |
206 | SV *output; | |
207 | ||
208 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
209 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
210 | if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); | |
211 | if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); | |
212 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
213 | ||
214 | id = _find_cipher(cipher_name); | |
215 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
216 | output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ | |
217 | SvPOK_only(output); | |
218 | SvCUR_set(output, ct_len); | |
219 | tag_len = (unsigned long)t_len; | |
220 | Copy(t, tag, t_len, unsigned char); | |
221 | ||
222 | rv = eax_decrypt_verify_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
223 | ct, (unsigned long)ct_len, (unsigned char *)SvPVX(output), tag, tag_len, &stat); | |
224 | ||
225 | if (rv != CRYPT_OK || stat != 1) { | |
226 | SvREFCNT_dec(output); | |
227 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ | |
228 | } | |
229 | else { | |
230 | XPUSHs(sv_2mortal(output)); | |
231 | } | |
232 | } |
6 | 6 | STRLEN k_len = 0, iv_len = 0; |
7 | 7 | unsigned char *k = NULL, *iv = NULL; |
8 | 8 | int id, rv; |
9 | LTC_UNUSED_PARAM(class); | |
9 | 10 | |
10 | 11 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
11 | 12 | k = (unsigned char *) SvPVbyte(key, k_len); |
75 | 76 | } |
76 | 77 | else |
77 | 78 | { |
78 | RETVAL = NEWSV(0, in_data_len); | |
79 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
79 | 80 | SvPOK_only(RETVAL); |
80 | 81 | SvCUR_set(RETVAL, in_data_len); |
81 | 82 | out_data = (unsigned char *)SvPVX(RETVAL); |
130 | 131 | RETVAL = newSVpvn("", 0); |
131 | 132 | } |
132 | 133 | else { |
133 | RETVAL = NEWSV(0, in_data_len); | |
134 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
134 | 135 | SvPOK_only(RETVAL); |
135 | 136 | SvCUR_set(RETVAL, in_data_len); |
136 | 137 | out_data = (unsigned char *)SvPVX(RETVAL); |
187 | 188 | } |
188 | 189 | } |
189 | 190 | } |
191 | ||
192 | void | |
193 | gcm_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header = NULL, SV *plaintext) | |
194 | PPCODE: | |
195 | { | |
196 | STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; | |
197 | unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; | |
198 | int rv, id; | |
199 | unsigned char tag[MAXBLOCKSIZE]; | |
200 | unsigned long tag_len = sizeof(tag); | |
201 | SV *output; | |
202 | ||
203 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
204 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
205 | if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); | |
206 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
207 | ||
208 | id = _find_cipher(cipher_name); | |
209 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
210 | output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ | |
211 | SvPOK_only(output); | |
212 | SvCUR_set(output, pt_len); | |
213 | ||
214 | rv = gcm_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
215 | pt, (unsigned long)pt_len, (unsigned char *)SvPVX(output), tag, &tag_len, GCM_ENCRYPT); | |
216 | ||
217 | if (rv != CRYPT_OK) { | |
218 | SvREFCNT_dec(output); | |
219 | croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); | |
220 | } | |
221 | XPUSHs(sv_2mortal(output)); | |
222 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); | |
223 | } | |
224 | ||
225 | void | |
226 | gcm_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) | |
227 | PPCODE: | |
228 | { | |
229 | STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; | |
230 | unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; | |
231 | int rv, id; | |
232 | unsigned char tag[MAXBLOCKSIZE]; | |
233 | unsigned long tag_len; | |
234 | SV *output; | |
235 | ||
236 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
237 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
238 | if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); | |
239 | if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); | |
240 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
241 | ||
242 | id = _find_cipher(cipher_name); | |
243 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
244 | output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ | |
245 | SvPOK_only(output); | |
246 | SvCUR_set(output, ct_len); | |
247 | tag_len = (unsigned long)t_len; | |
248 | Copy(t, tag, t_len, unsigned char); | |
249 | ||
250 | rv = gcm_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len, | |
251 | (unsigned char *)SvPVX(output), (unsigned long)ct_len, ct, tag, &tag_len, GCM_DECRYPT); | |
252 | ||
253 | if (rv != CRYPT_OK) { | |
254 | SvREFCNT_dec(output); | |
255 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ | |
256 | } | |
257 | else { | |
258 | XPUSHs(sv_2mortal(output)); | |
259 | } | |
260 | } |
8 | 8 | unsigned char *n=NULL; |
9 | 9 | STRLEN n_len=0; |
10 | 10 | int rv, id; |
11 | LTC_UNUSED_PARAM(class); | |
11 | 12 | |
12 | 13 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 14 | k = (unsigned char *) SvPVbyte(key, k_len); |
76 | 77 | if (in_data_len % 16) { |
77 | 78 | croak ("FATAL: sizeof(data) should be multiple of 16"); |
78 | 79 | } |
79 | RETVAL = NEWSV(0, in_data_len); | |
80 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
80 | 81 | SvPOK_only(RETVAL); |
81 | 82 | SvCUR_set(RETVAL, in_data_len); |
82 | 83 | out_data = (unsigned char *)SvPVX(RETVAL); |
107 | 108 | RETVAL = newSVpvn("", 0); |
108 | 109 | } |
109 | 110 | else { |
110 | RETVAL = NEWSV(0, in_data_len); | |
111 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
111 | 112 | SvPOK_only(RETVAL); |
112 | 113 | SvCUR_set(RETVAL, in_data_len); |
113 | 114 | out_data = (unsigned char *)SvPVX(RETVAL); |
137 | 138 | if (in_data_len % 16) { |
138 | 139 | croak ("FATAL: sizeof(data) should be multiple of 16"); |
139 | 140 | } |
140 | RETVAL = NEWSV(0, in_data_len); | |
141 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
141 | 142 | SvPOK_only(RETVAL); |
142 | 143 | SvCUR_set(RETVAL, in_data_len); |
143 | 144 | out_data = (unsigned char *)SvPVX(RETVAL); |
168 | 169 | RETVAL = newSVpvn("", 0); |
169 | 170 | } |
170 | 171 | else { |
171 | RETVAL = NEWSV(0, in_data_len); | |
172 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
172 | 173 | SvPOK_only(RETVAL); |
173 | 174 | SvCUR_set(RETVAL, in_data_len); |
174 | 175 | out_data = (unsigned char *)SvPVX(RETVAL); |
225 | 226 | } |
226 | 227 | } |
227 | 228 | } |
229 | ||
230 | void | |
231 | ocb_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext) | |
232 | PPCODE: | |
233 | { | |
234 | STRLEN k_len = 0, n_len = 0, h_len = 0, pt_len = 0; | |
235 | unsigned char *k = NULL, *n = NULL, *h = NULL, *pt = NULL; | |
236 | int rv, id; | |
237 | unsigned char tag[MAXBLOCKSIZE]; | |
238 | SV *output; | |
239 | ||
240 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
241 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
242 | if (SvPOK(plaintext)) pt = (unsigned char *) SvPVbyte(plaintext, pt_len); | |
243 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
244 | ||
245 | id = _find_cipher(cipher_name); | |
246 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
247 | output = NEWSV(0, pt_len > 0 ? pt_len : 1); /* avoid zero! */ | |
248 | SvPOK_only(output); | |
249 | SvCUR_set(output, pt_len); | |
250 | if(tag_len < 4 || tag_len > 16) tag_len = 16; | |
251 | ||
252 | rv = ocb3_encrypt_authenticate_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, | |
253 | h, (unsigned long)h_len, pt, (unsigned long)pt_len, | |
254 | (unsigned char *)SvPVX(output), tag, &tag_len); | |
255 | ||
256 | if (rv != CRYPT_OK) { | |
257 | SvREFCNT_dec(output); | |
258 | croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); | |
259 | } | |
260 | XPUSHs(sv_2mortal(output)); | |
261 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); | |
262 | } | |
263 | ||
264 | void | |
265 | ocb_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tagsv) | |
266 | PPCODE: | |
267 | { | |
268 | STRLEN k_len = 0, n_len = 0, h_len = 0, ct_len = 0, t_len = 0; | |
269 | unsigned char *k = NULL, *n = NULL, *h = NULL, *ct = NULL, *t = NULL; | |
270 | int rv, id, stat = 0; | |
271 | SV *output; | |
272 | ||
273 | if (SvPOK(key)) k = (unsigned char *) SvPVbyte(key, k_len); | |
274 | if (SvPOK(nonce)) n = (unsigned char *) SvPVbyte(nonce, n_len); | |
275 | if (SvPOK(ciphertext)) ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); | |
276 | if (SvPOK(tagsv)) t = (unsigned char *) SvPVbyte(tagsv, t_len); | |
277 | if (SvPOK(header)) h = (unsigned char *) SvPVbyte(header, h_len); | |
278 | ||
279 | id = _find_cipher(cipher_name); | |
280 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); | |
281 | output = NEWSV(0, ct_len > 0 ? ct_len : 1); /* avoid zero! */ | |
282 | SvPOK_only(output); | |
283 | SvCUR_set(output, ct_len); | |
284 | ||
285 | rv = ocb3_decrypt_verify_memory(id, k, (unsigned long)k_len, n, (unsigned long)n_len, | |
286 | h, (unsigned long)h_len, ct, (unsigned long)ct_len, | |
287 | (unsigned char *)SvPVX(output), t, (unsigned long)t_len, &stat); | |
288 | ||
289 | if (rv != CRYPT_OK || stat != 1) { | |
290 | SvREFCNT_dec(output); | |
291 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ | |
292 | } | |
293 | else { | |
294 | XPUSHs(sv_2mortal(output)); | |
295 | } | |
296 | } |
56 | 56 | RETVAL = newSVpvn("", 0); |
57 | 57 | } |
58 | 58 | else if (len == (STRLEN)self->desc->block_length) { |
59 | RETVAL = NEWSV(0, len); | |
59 | RETVAL = NEWSV(0, len); /* avoid zero! */ | |
60 | 60 | SvPOK_only(RETVAL); |
61 | 61 | SvCUR_set(RETVAL, len); |
62 | 62 | rv = self->desc->ecb_encrypt((unsigned char *)plaintext, (unsigned char *)SvPVX(RETVAL), &self->skey); |
84 | 84 | RETVAL = newSVpvn("", 0); |
85 | 85 | } |
86 | 86 | else if (len == (STRLEN)self->desc->block_length) { |
87 | RETVAL = NEWSV(0, len); | |
87 | RETVAL = NEWSV(0, len); /* avoid zero! */ | |
88 | 88 | SvPOK_only(RETVAL); |
89 | 89 | SvCUR_set(RETVAL, len); |
90 | 90 | rv = self->desc->ecb_decrypt((unsigned char *)ciphertext, (unsigned char *)SvPVX(RETVAL), &self->skey); |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | int rv; |
7 | LTC_UNUSED_PARAM(class); | |
7 | 8 | |
8 | 9 | Newz(0, RETVAL, 1, struct digest_shake_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
67 | 68 | int rv; |
68 | 69 | unsigned char *out_data; |
69 | 70 | |
70 | RETVAL = NEWSV(0, out_len); | |
71 | SvPOK_only(RETVAL); | |
72 | SvCUR_set(RETVAL, out_len); | |
73 | out_data = (unsigned char *)SvPVX(RETVAL); | |
74 | rv = sha3_shake_done(&self->state, out_data, (unsigned long)out_len); | |
75 | if (rv != CRYPT_OK) { | |
76 | SvREFCNT_dec(RETVAL); | |
77 | croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv)); | |
71 | if (out_len == 0) { | |
72 | RETVAL = newSVpvn("", 0); | |
73 | } | |
74 | else { | |
75 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
76 | SvPOK_only(RETVAL); | |
77 | SvCUR_set(RETVAL, out_len); | |
78 | out_data = (unsigned char *)SvPVX(RETVAL); | |
79 | rv = sha3_shake_done(&self->state, out_data, (unsigned long)out_len); | |
80 | if (rv != CRYPT_OK) { | |
81 | SvREFCNT_dec(RETVAL); | |
82 | croak("FATAL: sha3_shake_done failed: %s", error_to_string(rv)); | |
83 | } | |
78 | 84 | } |
79 | 85 | } |
80 | 86 | OUTPUT: |
0 | 0 | MODULE = CryptX PACKAGE = Crypt::KeyDerivation |
1 | 1 | |
2 | 2 | SV * |
3 | _pkcs_5_alg1(SV * password, SV * salt, int iteration_count, char * hash_name, unsigned long output_len) | |
3 | pbkdf1(SV * password, SV * salt, int iteration_count = 5000, const char * hash_name = "SHA256", unsigned long output_len = 32) | |
4 | 4 | CODE: |
5 | 5 | { |
6 | /* | |
7 | int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, | |
8 | const unsigned char *salt, | |
9 | int iteration_count, int hash_idx, | |
10 | unsigned char *out, unsigned long *outlen) | |
11 | */ | |
12 | 6 | int rv, id; |
13 | 7 | unsigned char *output; |
14 | 8 | unsigned char *password_ptr=NULL; |
16 | 10 | unsigned char *salt_ptr=NULL; |
17 | 11 | STRLEN salt_len=0; |
18 | 12 | |
19 | id = _find_hash(hash_name); | |
20 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
13 | if (output_len == 0) { | |
14 | RETVAL = newSVpvn("", 0); | |
15 | } | |
16 | else { | |
17 | id = _find_hash(hash_name); | |
18 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
21 | 19 | |
22 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); | |
23 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
24 | if (salt_len < 8) croak("FATAL: salt_len has to be 8"); | |
20 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); | |
21 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
22 | if (salt_len < 8) croak("FATAL: salt_len has to be 8"); | |
25 | 23 | |
26 | RETVAL = NEWSV(0, output_len); | |
27 | SvPOK_only(RETVAL); | |
28 | SvCUR_set(RETVAL, output_len); | |
29 | output = (unsigned char *)SvPVX(RETVAL); | |
24 | RETVAL = NEWSV(0, output_len); /* avoid zero! */ | |
25 | SvPOK_only(RETVAL); | |
26 | SvCUR_set(RETVAL, output_len); | |
27 | output = (unsigned char *)SvPVX(RETVAL); | |
30 | 28 | |
31 | rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); | |
32 | if (rv != CRYPT_OK) { | |
33 | SvREFCNT_dec(RETVAL); | |
34 | croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); | |
29 | rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); | |
30 | if (rv != CRYPT_OK) { | |
31 | SvREFCNT_dec(RETVAL); | |
32 | croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); | |
33 | } | |
34 | SvCUR_set(RETVAL, output_len); | |
35 | 35 | } |
36 | SvCUR_set(RETVAL, output_len); | |
37 | 36 | } |
38 | 37 | OUTPUT: |
39 | 38 | RETVAL |
40 | 39 | |
41 | 40 | SV * |
42 | _pkcs_5_alg2(SV * password, SV * salt, int iteration_count, char * hash_name, unsigned long output_len) | |
41 | pbkdf2(SV * password, SV * salt, int iteration_count = 5000, const char * hash_name = "SHA256", unsigned long output_len = 32) | |
43 | 42 | CODE: |
44 | 43 | { |
45 | /* | |
46 | int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, | |
47 | const unsigned char *salt, unsigned long salt_len, | |
48 | int iteration_count, int hash_idx, | |
49 | unsigned char *out, unsigned long *outlen) | |
50 | */ | |
51 | 44 | int rv, id; |
52 | 45 | unsigned char *output; |
53 | 46 | unsigned char *password_ptr=NULL; |
55 | 48 | unsigned char *salt_ptr=NULL; |
56 | 49 | STRLEN salt_len=0; |
57 | 50 | |
58 | id = _find_hash(hash_name); | |
59 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
51 | if (output_len == 0) { | |
52 | RETVAL = newSVpvn("", 0); | |
53 | } | |
54 | else { | |
55 | id = _find_hash(hash_name); | |
56 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
60 | 57 | |
61 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); | |
62 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
58 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); | |
59 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
63 | 60 | |
64 | RETVAL = NEWSV(0, output_len); | |
65 | SvPOK_only(RETVAL); | |
66 | SvCUR_set(RETVAL, output_len); | |
67 | output = (unsigned char *)SvPVX(RETVAL); | |
61 | RETVAL = NEWSV(0, output_len); /* avoid zero! */ | |
62 | SvPOK_only(RETVAL); | |
63 | SvCUR_set(RETVAL, output_len); | |
64 | output = (unsigned char *)SvPVX(RETVAL); | |
68 | 65 | |
69 | rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); | |
70 | if (rv != CRYPT_OK) { | |
71 | SvREFCNT_dec(RETVAL); | |
72 | croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); | |
66 | rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); | |
67 | if (rv != CRYPT_OK) { | |
68 | SvREFCNT_dec(RETVAL); | |
69 | croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); | |
70 | } | |
71 | SvCUR_set(RETVAL, output_len); | |
73 | 72 | } |
74 | SvCUR_set(RETVAL, output_len); | |
75 | 73 | } |
76 | 74 | OUTPUT: |
77 | 75 | RETVAL |
78 | 76 | |
79 | 77 | SV * |
80 | _hkdf_extract(char * hash_name, SV * salt, SV * in) | |
78 | hkdf_extract(SV * in, SV * salt = &PL_sv_undef, const char * hash_name = "SHA256") | |
81 | 79 | CODE: |
82 | 80 | { |
83 | /* | |
84 | int hkdf_extract(int hash_idx, const unsigned char *salt, unsigned long saltlen, | |
85 | const unsigned char *in, unsigned long inlen, | |
86 | unsigned char *out, unsigned long *outlen) | |
87 | */ | |
88 | 81 | int rv, id; |
89 | 82 | unsigned char output[MAXBLOCKSIZE]; |
90 | 83 | unsigned long output_len; |
91 | unsigned char *in_ptr=NULL; | |
92 | STRLEN in_len=0; | |
93 | unsigned char *salt_ptr=NULL; | |
94 | STRLEN salt_len=0; | |
84 | unsigned char *in_ptr = NULL, *salt_ptr = NULL; | |
85 | STRLEN in_len = 0, salt_len = 0; | |
95 | 86 | |
96 | 87 | id = _find_hash(hash_name); |
97 | 88 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); |
98 | 89 | |
99 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
100 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
90 | if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
91 | if (SvPOK(salt)) salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
101 | 92 | |
102 | 93 | output_len = sizeof(output); |
103 | 94 | rv = hkdf_extract(id, salt_ptr, (unsigned long)salt_len, in_ptr, (unsigned long)in_len, output, &output_len); |
109 | 100 | RETVAL |
110 | 101 | |
111 | 102 | SV * |
112 | _hkdf_expand(char * hash_name, SV * info, SV * in, unsigned long output_len) | |
103 | hkdf_expand(SV * in, const char * hash_name = "SHA256", unsigned long output_len = 32, SV * info = &PL_sv_undef) | |
113 | 104 | CODE: |
114 | 105 | { |
115 | /* | |
116 | int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen, | |
117 | const unsigned char *in, unsigned long inlen, | |
118 | unsigned char *out, unsigned long outlen) | |
119 | */ | |
120 | 106 | int rv, id; |
121 | 107 | unsigned char *output; |
122 | unsigned char *in_ptr=NULL; | |
123 | STRLEN in_len=0; | |
124 | unsigned char *info_ptr=NULL; | |
125 | STRLEN info_len=0; | |
108 | unsigned char *in_ptr = NULL, *info_ptr = NULL; | |
109 | STRLEN in_len = 0, info_len = 0; | |
126 | 110 | |
127 | id = _find_hash(hash_name); | |
128 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
111 | if (output_len == 0) { | |
112 | RETVAL = newSVpvn("", 0); | |
113 | } | |
114 | else { | |
115 | id = _find_hash(hash_name); | |
116 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
129 | 117 | |
130 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
131 | info_ptr = (unsigned char *)SvPVbyte(info, info_len); | |
118 | if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
119 | if (SvPOK(info)) info_ptr = (unsigned char *)SvPVbyte(info, info_len); | |
132 | 120 | |
133 | RETVAL = NEWSV(0, output_len); | |
134 | SvPOK_only(RETVAL); | |
135 | SvCUR_set(RETVAL, output_len); | |
136 | output = (unsigned char *)SvPVX(RETVAL); | |
121 | RETVAL = NEWSV(0, output_len); /* avoid zero! */ | |
122 | SvPOK_only(RETVAL); | |
123 | SvCUR_set(RETVAL, output_len); | |
124 | output = (unsigned char *)SvPVX(RETVAL); | |
137 | 125 | |
138 | rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); | |
139 | if (rv != CRYPT_OK) { | |
140 | SvREFCNT_dec(RETVAL); | |
141 | croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); | |
126 | rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); | |
127 | if (rv != CRYPT_OK) { | |
128 | SvREFCNT_dec(RETVAL); | |
129 | croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); | |
130 | } | |
131 | SvCUR_set(RETVAL, output_len); | |
142 | 132 | } |
143 | SvCUR_set(RETVAL, output_len); | |
144 | 133 | } |
145 | 134 | OUTPUT: |
146 | 135 | RETVAL |
147 | 136 | |
148 | 137 | SV * |
149 | _hkdf(char * hash_name, SV * salt, SV * info, SV * in, unsigned long output_len) | |
138 | hkdf(SV * in, SV * salt, const char * hash_name = "SHA256", unsigned long output_len = 32, SV * info = &PL_sv_undef) | |
150 | 139 | CODE: |
151 | 140 | { |
152 | /* | |
153 | int hkdf(int hash_idx, const unsigned char *salt, unsigned long saltlen, | |
154 | const unsigned char *info, unsigned long infolen, | |
155 | const unsigned char *in, unsigned long inlen, | |
156 | unsigned char *out, unsigned long outlen) | |
157 | */ | |
158 | 141 | int rv, id; |
159 | 142 | unsigned char *output; |
160 | unsigned char *in_ptr=NULL; | |
161 | STRLEN in_len=0; | |
162 | unsigned char *info_ptr=NULL; | |
163 | STRLEN info_len=0; | |
164 | unsigned char *salt_ptr=NULL; | |
165 | STRLEN salt_len=0; | |
143 | unsigned char *in_ptr = NULL, *info_ptr = NULL, *salt_ptr = NULL; | |
144 | STRLEN in_len = 0, info_len = 0, salt_len = 0; | |
166 | 145 | |
167 | id = _find_hash(hash_name); | |
168 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
146 | if (output_len == 0) { | |
147 | RETVAL = newSVpvn("", 0); | |
148 | } | |
149 | else { | |
150 | id = _find_hash(hash_name); | |
151 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
169 | 152 | |
170 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
171 | info_ptr = (unsigned char *)SvPVbyte(info, info_len); | |
172 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
153 | if (SvPOK(in)) in_ptr = (unsigned char *)SvPVbyte(in, in_len); | |
154 | if (SvPOK(info)) info_ptr = (unsigned char *)SvPVbyte(info, info_len); | |
155 | if (SvPOK(salt)) salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); | |
173 | 156 | |
174 | RETVAL = NEWSV(0, output_len); | |
175 | SvPOK_only(RETVAL); | |
176 | SvCUR_set(RETVAL, output_len); | |
177 | output = (unsigned char *)SvPVX(RETVAL); | |
157 | RETVAL = NEWSV(0, output_len); /* avoid zero! */ | |
158 | SvPOK_only(RETVAL); | |
159 | SvCUR_set(RETVAL, output_len); | |
160 | output = (unsigned char *)SvPVX(RETVAL); | |
178 | 161 | |
179 | rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); | |
180 | if (rv != CRYPT_OK) { | |
181 | SvREFCNT_dec(RETVAL); | |
182 | croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); | |
162 | rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); | |
163 | if (rv != CRYPT_OK) { | |
164 | SvREFCNT_dec(RETVAL); | |
165 | croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); | |
166 | } | |
167 | SvCUR_set(RETVAL, output_len); | |
183 | 168 | } |
184 | SvCUR_set(RETVAL, output_len); | |
185 | 169 | } |
186 | 170 | OUTPUT: |
187 | 171 | RETVAL |
9 | 9 | unsigned char *k=NULL; |
10 | 10 | int rv; |
11 | 11 | |
12 | LTC_UNUSED_PARAM(class); | |
12 | 13 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 14 | k = (unsigned char *) SvPVbyte(key, k_len); |
14 | 15 | |
89 | 90 | RETVAL = newSVpvn(out, outlen); |
90 | 91 | } |
91 | 92 | else { |
92 | RETVAL = newSVpvn(mac, maclen); | |
93 | RETVAL = newSVpvn((char * )mac, maclen); | |
93 | 94 | } |
94 | 95 | } |
95 | 96 | OUTPUT: |
113 | 114 | blake2bmac_state st; |
114 | 115 | |
115 | 116 | if (size < len) len = size; |
116 | rv = blake2bmac_init(&st, len, k, klen); | |
117 | rv = blake2bmac_init(&st, len, k, (unsigned long)klen); | |
117 | 118 | if (rv != CRYPT_OK) croak("FATAL: blake2bmac_init failed: %s", error_to_string(rv)); |
118 | 119 | for (i = 2; i < items; i++) { |
119 | 120 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
120 | 121 | if (inlen > 0) { |
121 | rv = blake2bmac_process(&st, in, inlen); | |
122 | rv = blake2bmac_process(&st, in, (unsigned long)inlen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: blake2bmac_process failed: %s", error_to_string(rv)); |
123 | 124 | } |
124 | 125 | } |
9 | 9 | unsigned char *k=NULL; |
10 | 10 | int rv; |
11 | 11 | |
12 | LTC_UNUSED_PARAM(class); | |
12 | 13 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 14 | k = (unsigned char *) SvPVbyte(key, k_len); |
14 | 15 | |
89 | 90 | RETVAL = newSVpvn(out, outlen); |
90 | 91 | } |
91 | 92 | else { |
92 | RETVAL = newSVpvn(mac, maclen); | |
93 | RETVAL = newSVpvn((char * )mac, maclen); | |
93 | 94 | } |
94 | 95 | } |
95 | 96 | OUTPUT: |
113 | 114 | blake2smac_state st; |
114 | 115 | |
115 | 116 | if (size < len) len = size; |
116 | rv = blake2smac_init(&st, len, k, klen); | |
117 | rv = blake2smac_init(&st, len, k, (unsigned long)klen); | |
117 | 118 | if (rv != CRYPT_OK) croak("FATAL: blake2smac_init failed: %s", error_to_string(rv)); |
118 | 119 | for (i = 2; i < items; i++) { |
119 | 120 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
120 | 121 | if (inlen > 0) { |
121 | rv = blake2smac_process(&st, in, inlen); | |
122 | rv = blake2smac_process(&st, in, (unsigned long)inlen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: blake2smac_process failed: %s", error_to_string(rv)); |
123 | 124 | } |
124 | 125 | } |
13 | 13 | id = _find_cipher(cipher_name); |
14 | 14 | if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
15 | 15 | |
16 | LTC_UNUSED_PARAM(class); | |
16 | 17 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
17 | 18 | k = (unsigned char *) SvPVbyte(key, k_len); |
18 | 19 | |
93 | 94 | RETVAL = newSVpvn(out, outlen); |
94 | 95 | } |
95 | 96 | else { |
96 | RETVAL = newSVpvn(mac, maclen); | |
97 | RETVAL = newSVpvn((char * )mac, maclen); | |
97 | 98 | } |
98 | 99 | } |
99 | 100 | OUTPUT: |
118 | 119 | |
119 | 120 | int id = _find_cipher(cipher_name); |
120 | 121 | if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); |
121 | rv = f9_init(&st, id, k, klen); | |
122 | rv = f9_init(&st, id, k, (unsigned long)klen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: f9_init failed: %s", error_to_string(rv)); |
123 | 124 | for (i = 2; i < items; i++) { |
124 | 125 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
125 | 126 | if (inlen > 0) { |
126 | rv = f9_process(&st, in, inlen); | |
127 | rv = f9_process(&st, in, (unsigned long)inlen); | |
127 | 128 | if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); |
128 | 129 | } |
129 | 130 | } |
13 | 13 | id = _find_hash(hash_name); |
14 | 14 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); |
15 | 15 | |
16 | LTC_UNUSED_PARAM(class); | |
16 | 17 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
17 | 18 | k = (unsigned char *) SvPVbyte(key, k_len); |
18 | 19 | |
93 | 94 | RETVAL = newSVpvn(out, outlen); |
94 | 95 | } |
95 | 96 | else { |
96 | RETVAL = newSVpvn(mac, maclen); | |
97 | RETVAL = newSVpvn((char * )mac, maclen); | |
97 | 98 | } |
98 | 99 | } |
99 | 100 | OUTPUT: |
118 | 119 | |
119 | 120 | int id = _find_hash(hash_name); |
120 | 121 | if (id == -1) croak("FATAL: find_digest failed for '%s'", hash_name); |
121 | rv = hmac_init(&st, id, k, klen); | |
122 | rv = hmac_init(&st, id, k, (unsigned long)klen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: hmac_init failed: %s", error_to_string(rv)); |
123 | 124 | for (i = 2; i < items; i++) { |
124 | 125 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
125 | 126 | if (inlen > 0) { |
126 | rv = hmac_process(&st, in, inlen); | |
127 | rv = hmac_process(&st, in, (unsigned long)inlen); | |
127 | 128 | if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); |
128 | 129 | } |
129 | 130 | } |
13 | 13 | id = _find_cipher(cipher_name); |
14 | 14 | if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
15 | 15 | |
16 | LTC_UNUSED_PARAM(class); | |
16 | 17 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
17 | 18 | k = (unsigned char *) SvPVbyte(key, k_len); |
18 | 19 | |
93 | 94 | RETVAL = newSVpvn(out, outlen); |
94 | 95 | } |
95 | 96 | else { |
96 | RETVAL = newSVpvn(mac, maclen); | |
97 | RETVAL = newSVpvn((char * )mac, maclen); | |
97 | 98 | } |
98 | 99 | } |
99 | 100 | OUTPUT: |
118 | 119 | |
119 | 120 | int id = _find_cipher(cipher_name); |
120 | 121 | if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); |
121 | rv = omac_init(&st, id, k, klen); | |
122 | rv = omac_init(&st, id, k, (unsigned long)klen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: omac_init failed: %s", error_to_string(rv)); |
123 | 124 | for (i = 2; i < items; i++) { |
124 | 125 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
125 | 126 | if (inlen > 0) { |
126 | rv = omac_process(&st, in, inlen); | |
127 | rv = omac_process(&st, in, (unsigned long)inlen); | |
127 | 128 | if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); |
128 | 129 | } |
129 | 130 | } |
13 | 13 | id = _find_cipher(cipher_name); |
14 | 14 | if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
15 | 15 | |
16 | LTC_UNUSED_PARAM(class); | |
16 | 17 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
17 | 18 | k = (unsigned char *) SvPVbyte(key, k_len); |
18 | 19 | |
93 | 94 | RETVAL = newSVpvn(out, outlen); |
94 | 95 | } |
95 | 96 | else { |
96 | RETVAL = newSVpvn(mac, maclen); | |
97 | RETVAL = newSVpvn((char * )mac, maclen); | |
97 | 98 | } |
98 | 99 | } |
99 | 100 | OUTPUT: |
118 | 119 | |
119 | 120 | int id = _find_cipher(cipher_name); |
120 | 121 | if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); |
121 | rv = pmac_init(&st, id, k, klen); | |
122 | rv = pmac_init(&st, id, k, (unsigned long)klen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: pmac_init failed: %s", error_to_string(rv)); |
123 | 124 | for (i = 2; i < items; i++) { |
124 | 125 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
125 | 126 | if (inlen > 0) { |
126 | rv = pmac_process(&st, in, inlen); | |
127 | rv = pmac_process(&st, in, (unsigned long)inlen); | |
127 | 128 | if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); |
128 | 129 | } |
129 | 130 | } |
9 | 9 | unsigned char *k=NULL; |
10 | 10 | int rv; |
11 | 11 | |
12 | LTC_UNUSED_PARAM(class); | |
12 | 13 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 14 | k = (unsigned char *) SvPVbyte(key, k_len); |
14 | 15 | |
89 | 90 | RETVAL = newSVpvn(out, outlen); |
90 | 91 | } |
91 | 92 | else { |
92 | RETVAL = newSVpvn(mac, maclen); | |
93 | RETVAL = newSVpvn((char * )mac, maclen); | |
93 | 94 | } |
94 | 95 | } |
95 | 96 | OUTPUT: |
113 | 114 | pelican_state st; |
114 | 115 | |
115 | 116 | len = 16; |
116 | rv = pelican_init(&st, k, klen); | |
117 | rv = pelican_init(&st, k, (unsigned long)klen); | |
117 | 118 | if (rv != CRYPT_OK) croak("FATAL: pelican_init failed: %s", error_to_string(rv)); |
118 | 119 | for (i = 1; i < items; i++) { |
119 | 120 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
120 | 121 | if (inlen > 0) { |
121 | rv = pelican_process(&st, in, inlen); | |
122 | rv = pelican_process(&st, in, (unsigned long)inlen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); |
123 | 124 | } |
124 | 125 | } |
9 | 9 | unsigned char *k=NULL; |
10 | 10 | int rv; |
11 | 11 | |
12 | LTC_UNUSED_PARAM(class); | |
12 | 13 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 14 | k = (unsigned char *) SvPVbyte(key, k_len); |
14 | 15 | |
89 | 90 | RETVAL = newSVpvn(out, outlen); |
90 | 91 | } |
91 | 92 | else { |
92 | RETVAL = newSVpvn(mac, maclen); | |
93 | RETVAL = newSVpvn((char * )mac, maclen); | |
93 | 94 | } |
94 | 95 | } |
95 | 96 | OUTPUT: |
112 | 113 | char out[MAXBLOCKSIZE*2]; |
113 | 114 | poly1305_state st; |
114 | 115 | |
115 | rv = poly1305_init(&st, k, klen); | |
116 | rv = poly1305_init(&st, k, (unsigned long)klen); | |
116 | 117 | if (rv != CRYPT_OK) croak("FATAL: poly1305_init failed: %s", error_to_string(rv)); |
117 | 118 | for (i = 1; i < items; i++) { |
118 | 119 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
119 | 120 | if (inlen > 0) { |
120 | rv = poly1305_process(&st, in, inlen); | |
121 | rv = poly1305_process(&st, in, (unsigned long)inlen); | |
121 | 122 | if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv)); |
122 | 123 | } |
123 | 124 | } |
13 | 13 | id = _find_cipher(cipher_name); |
14 | 14 | if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
15 | 15 | |
16 | LTC_UNUSED_PARAM(class); | |
16 | 17 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
17 | 18 | k = (unsigned char *) SvPVbyte(key, k_len); |
18 | 19 | |
93 | 94 | RETVAL = newSVpvn(out, outlen); |
94 | 95 | } |
95 | 96 | else { |
96 | RETVAL = newSVpvn(mac, maclen); | |
97 | RETVAL = newSVpvn((char * )mac, maclen); | |
97 | 98 | } |
98 | 99 | } |
99 | 100 | OUTPUT: |
118 | 119 | |
119 | 120 | int id = _find_cipher(cipher_name); |
120 | 121 | if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name); |
121 | rv = xcbc_init(&st, id, k, klen); | |
122 | rv = xcbc_init(&st, id, k, (unsigned long)klen); | |
122 | 123 | if (rv != CRYPT_OK) croak("FATAL: xcbc_init failed: %s", error_to_string(rv)); |
123 | 124 | for (i = 2; i < items; i++) { |
124 | 125 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
125 | 126 | if (inlen > 0) { |
126 | rv = xcbc_process(&st, in, inlen); | |
127 | rv = xcbc_process(&st, in, (unsigned long)inlen); | |
127 | 128 | if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); |
128 | 129 | } |
129 | 130 | } |
5 | 5 | new(char * class, char * cipher_name, int padding=1, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct cbc_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->padding_mode = padding; |
26 | 27 | Safefree(self); |
27 | 28 | |
28 | 29 | void |
29 | _start(Crypt::Mode::CBC self, SV * key, SV * iv) | |
30 | start_decrypt(Crypt::Mode::CBC self, SV * key, SV * iv) | |
30 | 31 | ALIAS: |
31 | 32 | start_encrypt = 1 |
32 | start_decrypt = 2 | |
33 | 33 | PPCODE: |
34 | 34 | { |
35 | 35 | int rv; |
101 | 101 | |
102 | 102 | if (in_data_len > 0) { |
103 | 103 | i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); |
104 | RETVAL = NEWSV(0, i); | |
104 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
105 | 105 | SvPOK_only(RETVAL); |
106 | 106 | SvCUR_set(RETVAL, i); |
107 | 107 | out_data = (unsigned char *)SvPVX(RETVAL); |
182 | 182 | RETVAL = newSVpvn("", 0); |
183 | 183 | } |
184 | 184 | else { |
185 | RETVAL = NEWSV(0, i); | |
185 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
186 | 186 | SvPOK_only(RETVAL); |
187 | 187 | SvCUR_set(RETVAL, i); |
188 | 188 | out_data = (unsigned char *)SvPVX(RETVAL); |
5 | 5 | new(char * class, char * cipher_name, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct cfb_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->direction = 0; |
24 | 25 | Safefree(self); |
25 | 26 | |
26 | 27 | void |
27 | _start(Crypt::Mode::CFB self, SV * key, SV * iv) | |
28 | start_decrypt(Crypt::Mode::CFB self, SV * key, SV * iv) | |
28 | 29 | ALIAS: |
29 | 30 | start_encrypt = 1 |
30 | start_decrypt = 2 | |
31 | 31 | PPCODE: |
32 | 32 | { |
33 | 33 | STRLEN k_len=0; |
67 | 67 | RETVAL = newSVpvn("", 0); |
68 | 68 | } |
69 | 69 | else { |
70 | RETVAL = NEWSV(0, in_data_len); | |
70 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
71 | 71 | SvPOK_only(RETVAL); |
72 | 72 | SvCUR_set(RETVAL, in_data_len); |
73 | 73 | out_data = (unsigned char *)SvPVX(RETVAL); |
5 | 5 | new(char * class, char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct ctr_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->direction = 0; |
29 | 30 | Safefree(self); |
30 | 31 | |
31 | 32 | void |
32 | _start(Crypt::Mode::CTR self, SV * key, SV * iv) | |
33 | start_decrypt(Crypt::Mode::CTR self, SV * key, SV * iv) | |
33 | 34 | ALIAS: |
34 | 35 | start_encrypt = 1 |
35 | start_decrypt = 2 | |
36 | 36 | PPCODE: |
37 | 37 | { |
38 | 38 | STRLEN k_len=0; |
72 | 72 | RETVAL = newSVpvn("", 0); |
73 | 73 | } |
74 | 74 | else { |
75 | RETVAL = NEWSV(0, in_data_len); | |
75 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
76 | 76 | SvPOK_only(RETVAL); |
77 | 77 | SvCUR_set(RETVAL, in_data_len); |
78 | 78 | out_data = (unsigned char *)SvPVX(RETVAL); |
5 | 5 | new(char * class, char * cipher_name, int padding=1, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct ecb_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->padding_mode = padding; |
26 | 27 | Safefree(self); |
27 | 28 | |
28 | 29 | void |
29 | _start(Crypt::Mode::ECB self, SV * key) | |
30 | start_decrypt(Crypt::Mode::ECB self, SV * key) | |
30 | 31 | ALIAS: |
31 | 32 | start_encrypt = 1 |
32 | start_decrypt = 2 | |
33 | 33 | PPCODE: |
34 | 34 | { |
35 | 35 | int rv; |
94 | 94 | |
95 | 95 | if (in_data_len > 0) { |
96 | 96 | i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); |
97 | RETVAL = NEWSV(0, i); | |
97 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
98 | 98 | SvPOK_only(RETVAL); |
99 | 99 | SvCUR_set(RETVAL, i); |
100 | 100 | out_data = (unsigned char *)SvPVX(RETVAL); |
175 | 175 | RETVAL = newSVpvn("", 0); |
176 | 176 | } |
177 | 177 | else { |
178 | RETVAL = NEWSV(0, i); | |
178 | RETVAL = NEWSV(0, i); /* avoid zero! */ | |
179 | 179 | SvPOK_only(RETVAL); |
180 | 180 | SvCUR_set(RETVAL, i); |
181 | 181 | out_data = (unsigned char *)SvPVX(RETVAL); |
5 | 5 | new(char * class, char * cipher_name, int rounds=0) |
6 | 6 | CODE: |
7 | 7 | { |
8 | LTC_UNUSED_PARAM(class); | |
8 | 9 | Newz(0, RETVAL, 1, struct ofb_struct); |
9 | 10 | if (!RETVAL) croak("FATAL: Newz failed"); |
10 | 11 | RETVAL->direction = 0; |
24 | 25 | Safefree(self); |
25 | 26 | |
26 | 27 | void |
27 | _start(Crypt::Mode::OFB self, SV * key, SV * iv) | |
28 | start_decrypt(Crypt::Mode::OFB self, SV * key, SV * iv) | |
28 | 29 | ALIAS: |
29 | 30 | start_encrypt = 1 |
30 | start_decrypt = 2 | |
31 | 31 | PPCODE: |
32 | 32 | { |
33 | 33 | STRLEN k_len=0; |
67 | 67 | RETVAL = newSVpvn("", 0); |
68 | 68 | } |
69 | 69 | else { |
70 | RETVAL = NEWSV(0, in_data_len); | |
70 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
71 | 71 | SvPOK_only(RETVAL); |
72 | 72 | SvCUR_set(RETVAL, in_data_len); |
73 | 73 | out_data = (unsigned char *)SvPVX(RETVAL); |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | int rv; |
7 | LTC_UNUSED_PARAM(class); | |
7 | 8 | Newz(0, RETVAL, 1, struct dh_struct); |
8 | 9 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 10 | RETVAL->key.type = -1; |
207 | 208 | not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_groupsize(&self->key)), 0); |
208 | 209 | /* type */ |
209 | 210 | not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); |
210 | if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ | |
211 | LTC_UNUSED_PARAM(not_used); | |
211 | 212 | RETVAL = newRV_noinc((SV*)rv_hash); |
212 | 213 | OUTPUT: |
213 | 214 | RETVAL |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | int rv; |
7 | LTC_UNUSED_PARAM(class); | |
7 | 8 | Newz(0, RETVAL, 1, struct dsa_struct); |
8 | 9 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 10 | RETVAL->key.type = -1; |
228 | 229 | not_used = hv_store(rv_hash, "size", 4, newSViv(qsize), 0); |
229 | 230 | /* type */ |
230 | 231 | not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); |
231 | if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ | |
232 | LTC_UNUSED_PARAM(not_used); | |
232 | 233 | RETVAL = newRV_noinc((SV*)rv_hash); |
233 | 234 | OUTPUT: |
234 | 235 | RETVAL |
260 | 261 | RETVAL |
261 | 262 | |
262 | 263 | SV * |
263 | encrypt(Crypt::PK::DSA self, SV * data, char * hash_name="SHA1") | |
264 | encrypt(Crypt::PK::DSA self, SV * data, const char * hash_name = "SHA1") | |
264 | 265 | CODE: |
265 | 266 | { |
266 | 267 | int rv, hash_id; |
302 | 303 | RETVAL |
303 | 304 | |
304 | 305 | SV * |
305 | sign_hash(Crypt::PK::DSA self, SV * data) | |
306 | CODE: | |
307 | { | |
308 | int rv; | |
309 | unsigned char *data_ptr=NULL; | |
310 | STRLEN data_len=0; | |
311 | unsigned char buffer[1024]; | |
312 | unsigned long buffer_len = 1024; | |
306 | sign_hash(Crypt::PK::DSA self, SV * data, const char * hash_name = "SHA1") | |
307 | ALIAS: | |
308 | sign_message = 1 | |
309 | CODE: | |
310 | { | |
311 | int rv, id; | |
312 | unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; | |
313 | unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; | |
314 | STRLEN data_len = 0; | |
313 | 315 | |
314 | 316 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
315 | ||
317 | if (ix == 1) { | |
318 | id = _find_hash(hash_name); | |
319 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
320 | rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
321 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
322 | data_ptr = tmp; | |
323 | data_len = tmp_len; | |
324 | } | |
316 | 325 | rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
317 | 326 | &self->pstate, self->pindex, |
318 | 327 | &self->key); |
323 | 332 | RETVAL |
324 | 333 | |
325 | 334 | int |
326 | verify_hash(Crypt::PK::DSA self, SV * sig, SV * data) | |
327 | CODE: | |
328 | { | |
329 | int rv, stat; | |
330 | unsigned char *data_ptr=NULL; | |
331 | STRLEN data_len=0; | |
332 | unsigned char *sig_ptr=NULL; | |
333 | STRLEN sig_len=0; | |
335 | verify_hash(Crypt::PK::DSA self, SV * sig, SV * data, const char * hash_name = "SHA1") | |
336 | ALIAS: | |
337 | verify_message = 1 | |
338 | CODE: | |
339 | { | |
340 | int rv, stat, id; | |
341 | unsigned char tmp[MAXBLOCKSIZE], *data_ptr = NULL, *sig_ptr = NULL; | |
342 | unsigned long tmp_len = MAXBLOCKSIZE; | |
343 | STRLEN data_len = 0, sig_len = 0; | |
334 | 344 | |
335 | 345 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
336 | 346 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
337 | ||
347 | if (ix == 1) { | |
348 | id = _find_hash(hash_name); | |
349 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
350 | rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
351 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
352 | data_ptr = tmp; | |
353 | data_len = tmp_len; | |
354 | } | |
338 | 355 | RETVAL = 1; |
339 | 356 | stat = 0; |
340 | 357 | rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | int rv; |
7 | LTC_UNUSED_PARAM(class); | |
7 | 8 | Newz(0, RETVAL, 1, struct ecc_struct); |
8 | 9 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 10 | RETVAL->pindex = find_prng("chacha20"); |
204 | 205 | not_used = hv_store(rv_hash, "size", 4, newSViv(esize), 0); |
205 | 206 | /* type */ |
206 | 207 | not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); |
207 | if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ | |
208 | LTC_UNUSED_PARAM(not_used); | |
208 | 209 | RETVAL = newRV_noinc((SV*)rv_hash); |
209 | 210 | OUTPUT: |
210 | 211 | RETVAL |
277 | 278 | RETVAL |
278 | 279 | |
279 | 280 | SV * |
280 | _encrypt(Crypt::PK::ECC self, SV * data, char * hash_name) | |
281 | encrypt(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1") | |
281 | 282 | CODE: |
282 | 283 | { |
283 | 284 | int rv, hash_id; |
300 | 301 | RETVAL |
301 | 302 | |
302 | 303 | SV * |
303 | _decrypt(Crypt::PK::ECC self, SV * data) | |
304 | decrypt(Crypt::PK::ECC self, SV * data) | |
304 | 305 | CODE: |
305 | 306 | { |
306 | 307 | int rv; |
319 | 320 | RETVAL |
320 | 321 | |
321 | 322 | SV * |
322 | _sign(Crypt::PK::ECC self, SV * data) | |
323 | sign_hash(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1") | |
323 | 324 | ALIAS: |
324 | _sign_rfc7518 = 1 | |
325 | CODE: | |
326 | { | |
327 | int rv; | |
328 | unsigned char *data_ptr=NULL; | |
329 | STRLEN data_len=0; | |
330 | unsigned char buffer[1024]; | |
331 | unsigned long buffer_len = 1024; | |
325 | sign_message = 1 | |
326 | sign_message_rfc7518 = 2 | |
327 | CODE: | |
328 | { | |
329 | int rv, id; | |
330 | unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; | |
331 | unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; | |
332 | STRLEN data_len = 0; | |
332 | 333 | |
333 | 334 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
334 | ||
335 | if (ix == 1) { | |
335 | if (ix == 1 || ix == 2) { | |
336 | id = _find_hash(hash_name); | |
337 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
338 | rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
339 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
340 | data_ptr = tmp; | |
341 | data_len = tmp_len; | |
342 | } | |
343 | if (ix == 2) { | |
336 | 344 | rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
337 | 345 | &self->pstate, self->pindex, |
338 | 346 | &self->key); |
349 | 357 | RETVAL |
350 | 358 | |
351 | 359 | int |
352 | _verify(Crypt::PK::ECC self, SV * sig, SV * data) | |
360 | verify_hash(Crypt::PK::ECC self, SV * sig, SV * data, const char * hash_name = "SHA1") | |
353 | 361 | ALIAS: |
354 | _verify_rfc7518 = 1 | |
355 | CODE: | |
356 | { | |
357 | int rv, stat; | |
358 | unsigned char *data_ptr=NULL; | |
359 | STRLEN data_len=0; | |
360 | unsigned char *sig_ptr=NULL; | |
361 | STRLEN sig_len=0; | |
362 | verify_message = 1 | |
363 | verify_message_rfc7518 = 2 | |
364 | CODE: | |
365 | { | |
366 | int rv, stat, id; | |
367 | unsigned char tmp[MAXBLOCKSIZE], *data_ptr = NULL, *sig_ptr = NULL; | |
368 | unsigned long tmp_len = MAXBLOCKSIZE; | |
369 | STRLEN data_len = 0, sig_len = 0; | |
362 | 370 | |
363 | 371 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
364 | 372 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
365 | ||
373 | if (ix == 1 || ix == 2) { | |
374 | id = _find_hash(hash_name); | |
375 | if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
376 | rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
377 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
378 | data_ptr = tmp; | |
379 | data_len = tmp_len; | |
380 | } | |
366 | 381 | RETVAL = 1; |
367 | 382 | stat = 0; |
368 | if (ix == 1) { | |
383 | if (ix == 2) { | |
369 | 384 | rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); |
370 | 385 | } |
371 | 386 | else { |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | int rv; |
7 | LTC_UNUSED_PARAM(class); | |
7 | 8 | Newz(0, RETVAL, 1, struct rsa_struct); |
8 | 9 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 10 | RETVAL->key.type = -1; |
260 | 261 | not_used = hv_store(rv_hash, "size", 4, newSViv(nsize), 0); |
261 | 262 | /* type */ |
262 | 263 | not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0); |
263 | if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */ | |
264 | LTC_UNUSED_PARAM(not_used); | |
264 | 265 | RETVAL = newRV_noinc((SV*)rv_hash); |
265 | 266 | OUTPUT: |
266 | 267 | RETVAL |
292 | 293 | RETVAL |
293 | 294 | |
294 | 295 | SV * |
295 | encrypt(Crypt::PK::RSA self, SV * data, char * padding="oaep", char * oaep_hash="SHA1", SV * oaep_lparam=NULL) | |
296 | encrypt(Crypt::PK::RSA self, SV * data, const char * padding = "oaep", const char * oaep_hash = "SHA1", SV * oaep_lparam = NULL) | |
296 | 297 | CODE: |
297 | 298 | { |
298 | 299 | int rv, hash_id; |
337 | 338 | RETVAL |
338 | 339 | |
339 | 340 | SV * |
340 | decrypt(Crypt::PK::RSA self, SV * data, char * padding="oaep", char * oaep_hash="SHA1", SV * oaep_lparam=NULL) | |
341 | decrypt(Crypt::PK::RSA self, SV * data, const char * padding = "oaep", const char * oaep_hash = "SHA1", SV * oaep_lparam = NULL) | |
341 | 342 | CODE: |
342 | 343 | { |
343 | 344 | int rv, hash_id, stat; |
382 | 383 | RETVAL |
383 | 384 | |
384 | 385 | SV * |
385 | sign_hash(Crypt::PK::RSA self, SV * data, char * hash_name="SHA1", char * padding="pss", unsigned long saltlen=12) | |
386 | sign_hash(Crypt::PK::RSA self, SV * data, const char * hash_name = "SHA1", const char * padding = "pss", unsigned long saltlen=12) | |
387 | ALIAS: | |
388 | sign_message = 1 | |
386 | 389 | CODE: |
387 | 390 | { |
388 | 391 | int rv, hash_id; |
389 | unsigned char *data_ptr=NULL; | |
390 | STRLEN data_len=0; | |
391 | unsigned char buffer[1024]; | |
392 | unsigned long buffer_len = 1024; | |
392 | unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL; | |
393 | unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024; | |
394 | STRLEN data_len = 0; | |
393 | 395 | |
394 | 396 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
395 | ||
396 | RETVAL = newSVpvn(NULL, 0); /* undef */ | |
397 | if (ix == 1) { | |
398 | hash_id = _find_hash(hash_name); | |
399 | if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
400 | rv = hash_memory(hash_id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
401 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
402 | data_ptr = tmp; | |
403 | data_len = tmp_len; | |
404 | } | |
397 | 405 | if (strnEQ(padding, "pss", 3)) { |
398 | 406 | hash_id = _find_hash(hash_name); |
399 | 407 | if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); |
426 | 434 | RETVAL |
427 | 435 | |
428 | 436 | int |
429 | verify_hash(Crypt::PK::RSA self, SV * sig, SV * data, char * hash_name="SHA1", char * padding="pss", unsigned long saltlen=12) | |
437 | verify_hash(Crypt::PK::RSA self, SV * sig, SV * data, const char * hash_name = "SHA1", const char * padding = "pss", unsigned long saltlen = 12) | |
438 | ALIAS: | |
439 | verify_message = 1 | |
430 | 440 | CODE: |
431 | 441 | { |
432 | 442 | int rv, hash_id, stat; |
433 | unsigned char *data_ptr=NULL; | |
434 | STRLEN data_len=0; | |
435 | unsigned char *sig_ptr=NULL; | |
436 | STRLEN sig_len=0; | |
437 | unsigned char buffer[1024]; | |
438 | unsigned long i, buffer_len = 1024; | |
443 | unsigned char tmp[MAXBLOCKSIZE], buffer[1024], *data_ptr = NULL, *sig_ptr = NULL; | |
444 | unsigned long i, tmp_len = MAXBLOCKSIZE, buffer_len = 1024; | |
445 | STRLEN data_len = 0, sig_len = 0; | |
439 | 446 | |
440 | 447 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
441 | 448 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
442 | ||
449 | if (ix == 1) { | |
450 | hash_id = _find_hash(hash_name); | |
451 | if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name); | |
452 | rv = hash_memory(hash_id, data_ptr, (unsigned long)data_len, tmp, &tmp_len); | |
453 | if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv)); | |
454 | data_ptr = tmp; | |
455 | data_len = tmp_len; | |
456 | } | |
443 | 457 | RETVAL = 1; |
444 | 458 | stat = 0; |
445 | 459 | if (strnEQ(padding, "pss", 3)) { |
8 | 8 | unsigned char *ent=NULL; |
9 | 9 | STRLEN ent_len=0; |
10 | 10 | unsigned char entropy_buf[40]; |
11 | char *default_name = "ChaCha20"; | |
12 | char *prng_name = default_name; | |
11 | char *prng_name = (char *)"ChaCha20"; | |
13 | 12 | SV *entropy = &PL_sv_undef; |
14 | 13 | |
15 | 14 | /* we need to handle: |
94 | 93 | } |
95 | 94 | |
96 | 95 | SV * |
97 | bytes(Crypt::PRNG self, STRLEN output_len) | |
96 | bytes(Crypt::PRNG self, unsigned long output_len) | |
98 | 97 | ALIAS: |
99 | 98 | bytes_hex = 1 |
100 | 99 | bytes_b64 = 2 |
107 | 106 | unsigned char *rdata, *tmp; |
108 | 107 | unsigned char entropy_buf[40]; |
109 | 108 | |
110 | if (self->last_pid != curpid) { | |
111 | if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed"); | |
112 | self->desc->add_entropy(entropy_buf, 40, &self->state); | |
113 | self->desc->ready(&self->state); | |
114 | self->last_pid = curpid; | |
115 | } | |
116 | ||
117 | if (ix == 1) { | |
118 | /* HEX */ | |
119 | Newz(0, tmp, output_len, unsigned char); | |
120 | if (tmp == NULL) croak("FATAL: Newz failed"); | |
121 | rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); | |
122 | if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); | |
123 | RETVAL = NEWSV(0, output_len * 2); | |
124 | SvPOK_only(RETVAL); | |
125 | SvCUR_set(RETVAL, output_len * 2); | |
126 | rdata = (unsigned char *)SvPVX(RETVAL); | |
127 | len = output_len * 2; | |
128 | rv = _base16_encode(tmp, output_len, rdata, &len); | |
129 | Safefree(tmp); | |
130 | if (rv != CRYPT_OK) { | |
131 | SvREFCNT_dec(RETVAL); | |
132 | croak("FATAL: base16_encode failed"); | |
133 | } | |
134 | } | |
135 | else if (ix == 2 || ix == 3) { | |
136 | /* BASE64 or BASE64URL */ | |
137 | Newz(0, tmp, output_len, unsigned char); | |
138 | if (tmp == NULL) croak("FATAL: Newz failed"); | |
139 | rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); | |
140 | if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); | |
141 | RETVAL = NEWSV(0, output_len * 2); | |
142 | SvPOK_only(RETVAL); | |
143 | SvCUR_set(RETVAL, output_len * 2); | |
144 | rdata = (unsigned char *)SvPVX(RETVAL); | |
145 | len = output_len * 2; | |
146 | rv = ix == 3 ? base64url_encode(tmp, output_len, rdata, &len) : | |
147 | base64_encode(tmp, output_len, rdata, &len); | |
148 | SvCUR_set(RETVAL, len); | |
149 | Safefree(tmp); | |
150 | if (rv != CRYPT_OK) { | |
151 | SvREFCNT_dec(RETVAL); | |
152 | croak(ix == 3 ? "FATAL: base64url_encode failed" : "FATAL: base64_encode failed"); | |
153 | } | |
109 | if (output_len == 0) { | |
110 | RETVAL = newSVpvn("", 0); | |
154 | 111 | } |
155 | 112 | else { |
156 | /* RAW BYTES */ | |
157 | RETVAL = NEWSV(0, output_len); | |
158 | SvPOK_only(RETVAL); | |
159 | SvCUR_set(RETVAL, output_len); | |
160 | rdata = (unsigned char *)SvPVX(RETVAL); | |
161 | rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state); | |
162 | if ((UV)rv_len != output_len) { | |
163 | SvREFCNT_dec(RETVAL); | |
164 | croak("FATAL: PRNG_read failed"); | |
113 | if (self->last_pid != curpid) { | |
114 | if (rng_get_bytes(entropy_buf, 40, NULL) != 40) croak("FATAL: rng_get_bytes failed"); | |
115 | self->desc->add_entropy(entropy_buf, 40, &self->state); | |
116 | self->desc->ready(&self->state); | |
117 | self->last_pid = curpid; | |
118 | } | |
119 | if (ix == 1) { | |
120 | /* HEX */ | |
121 | Newz(0, tmp, output_len, unsigned char); | |
122 | if (tmp == NULL) croak("FATAL: Newz failed"); | |
123 | rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); | |
124 | if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); | |
125 | RETVAL = NEWSV(0, output_len * 2); /* avoid zero! */ | |
126 | SvPOK_only(RETVAL); | |
127 | SvCUR_set(RETVAL, output_len * 2); | |
128 | rdata = (unsigned char *)SvPVX(RETVAL); | |
129 | len = output_len * 2; | |
130 | rv = _base16_encode(tmp, output_len, rdata, &len); | |
131 | Safefree(tmp); | |
132 | if (rv != CRYPT_OK) { | |
133 | SvREFCNT_dec(RETVAL); | |
134 | croak("FATAL: base16_encode failed"); | |
135 | } | |
136 | } | |
137 | else if (ix == 2 || ix == 3) { | |
138 | /* BASE64 or BASE64URL */ | |
139 | Newz(0, tmp, output_len, unsigned char); | |
140 | if (tmp == NULL) croak("FATAL: Newz failed"); | |
141 | rv_len = (self->desc->read)(tmp, (unsigned long)output_len, &self->state); | |
142 | if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed"); | |
143 | RETVAL = NEWSV(0, output_len * 2); /* avoid zero! */ | |
144 | SvPOK_only(RETVAL); | |
145 | SvCUR_set(RETVAL, output_len * 2); | |
146 | rdata = (unsigned char *)SvPVX(RETVAL); | |
147 | len = output_len * 2; | |
148 | rv = ix == 3 ? base64url_encode(tmp, output_len, rdata, &len) : | |
149 | base64_encode(tmp, output_len, rdata, &len); | |
150 | SvCUR_set(RETVAL, len); | |
151 | Safefree(tmp); | |
152 | if (rv != CRYPT_OK) { | |
153 | SvREFCNT_dec(RETVAL); | |
154 | croak(ix == 3 ? "FATAL: base64url_encode failed" : "FATAL: base64_encode failed"); | |
155 | } | |
156 | } | |
157 | else { | |
158 | /* RAW BYTES */ | |
159 | RETVAL = NEWSV(0, output_len); /* avoid zero! */ | |
160 | SvPOK_only(RETVAL); | |
161 | SvCUR_set(RETVAL, output_len); | |
162 | rdata = (unsigned char *)SvPVX(RETVAL); | |
163 | rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state); | |
164 | if ((UV)rv_len != output_len) { | |
165 | SvREFCNT_dec(RETVAL); | |
166 | croak("FATAL: PRNG_read failed"); | |
167 | } | |
165 | 168 | } |
166 | 169 | } |
167 | 170 | } |
65 | 65 | int rv; |
66 | 66 | unsigned char *out_data; |
67 | 67 | |
68 | RETVAL = NEWSV(0, out_len); | |
69 | SvPOK_only(RETVAL); | |
70 | SvCUR_set(RETVAL, out_len); | |
71 | out_data = (unsigned char *)SvPVX(RETVAL); | |
72 | rv = chacha_keystream(&self->state, out_data, (unsigned long)out_len); | |
73 | if (rv != CRYPT_OK) { | |
74 | SvREFCNT_dec(RETVAL); | |
75 | croak("FATAL: chacha_keystream failed: %s", error_to_string(rv)); | |
68 | if (out_len == 0) { | |
69 | RETVAL = newSVpvn("", 0); | |
70 | } | |
71 | else { | |
72 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
73 | SvPOK_only(RETVAL); | |
74 | SvCUR_set(RETVAL, out_len); | |
75 | out_data = (unsigned char *)SvPVX(RETVAL); | |
76 | rv = chacha_keystream(&self->state, out_data, (unsigned long)out_len); | |
77 | if (rv != CRYPT_OK) { | |
78 | SvREFCNT_dec(RETVAL); | |
79 | croak("FATAL: chacha_keystream failed: %s", error_to_string(rv)); | |
80 | } | |
76 | 81 | } |
77 | 82 | } |
78 | 83 | OUTPUT: |
91 | 96 | RETVAL = newSVpvn("", 0); |
92 | 97 | } |
93 | 98 | else { |
94 | RETVAL = NEWSV(0, in_data_len); | |
99 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
95 | 100 | SvPOK_only(RETVAL); |
96 | 101 | SvCUR_set(RETVAL, in_data_len); |
97 | 102 | out_data = (unsigned char *)SvPVX(RETVAL); |
44 | 44 | int rv; |
45 | 45 | unsigned char *out_data; |
46 | 46 | |
47 | RETVAL = NEWSV(0, out_len); | |
48 | SvPOK_only(RETVAL); | |
49 | SvCUR_set(RETVAL, out_len); | |
50 | out_data = (unsigned char *)SvPVX(RETVAL); | |
51 | rv = rc4_stream_keystream(&self->state, out_data, (unsigned long)out_len); | |
52 | if (rv != CRYPT_OK) { | |
53 | SvREFCNT_dec(RETVAL); | |
54 | croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv)); | |
47 | if (out_len == 0) { | |
48 | RETVAL = newSVpvn("", 0); | |
49 | } | |
50 | else { | |
51 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
52 | SvPOK_only(RETVAL); | |
53 | SvCUR_set(RETVAL, out_len); | |
54 | out_data = (unsigned char *)SvPVX(RETVAL); | |
55 | rv = rc4_stream_keystream(&self->state, out_data, (unsigned long)out_len); | |
56 | if (rv != CRYPT_OK) { | |
57 | SvREFCNT_dec(RETVAL); | |
58 | croak("FATAL: rc4_stream_keystream failed: %s", error_to_string(rv)); | |
59 | } | |
55 | 60 | } |
56 | 61 | } |
57 | 62 | OUTPUT: |
70 | 75 | RETVAL = newSVpvn("", 0); |
71 | 76 | } |
72 | 77 | else { |
73 | RETVAL = NEWSV(0, in_data_len); | |
78 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
74 | 79 | SvPOK_only(RETVAL); |
75 | 80 | SvCUR_set(RETVAL, in_data_len); |
76 | 81 | out_data = (unsigned char *)SvPVX(RETVAL); |
55 | 55 | int rv; |
56 | 56 | unsigned char *out_data; |
57 | 57 | |
58 | RETVAL = NEWSV(0, out_len); | |
59 | SvPOK_only(RETVAL); | |
60 | SvCUR_set(RETVAL, out_len); | |
61 | out_data = (unsigned char *)SvPVX(RETVAL); | |
62 | rv = rabbit_keystream(&self->state, out_data, (unsigned long)out_len); | |
63 | if (rv != CRYPT_OK) { | |
64 | SvREFCNT_dec(RETVAL); | |
65 | croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv)); | |
58 | if (out_len == 0) { | |
59 | RETVAL = newSVpvn("", 0); | |
60 | } | |
61 | else { | |
62 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
63 | SvPOK_only(RETVAL); | |
64 | SvCUR_set(RETVAL, out_len); | |
65 | out_data = (unsigned char *)SvPVX(RETVAL); | |
66 | rv = rabbit_keystream(&self->state, out_data, (unsigned long)out_len); | |
67 | if (rv != CRYPT_OK) { | |
68 | SvREFCNT_dec(RETVAL); | |
69 | croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv)); | |
70 | } | |
66 | 71 | } |
67 | 72 | } |
68 | 73 | OUTPUT: |
81 | 86 | RETVAL = newSVpvn("", 0); |
82 | 87 | } |
83 | 88 | else { |
84 | RETVAL = NEWSV(0, in_data_len); | |
89 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
85 | 90 | SvPOK_only(RETVAL); |
86 | 91 | SvCUR_set(RETVAL, in_data_len); |
87 | 92 | out_data = (unsigned char *)SvPVX(RETVAL); |
52 | 52 | int rv; |
53 | 53 | unsigned char *out_data; |
54 | 54 | |
55 | RETVAL = NEWSV(0, out_len); | |
56 | SvPOK_only(RETVAL); | |
57 | SvCUR_set(RETVAL, out_len); | |
58 | out_data = (unsigned char *)SvPVX(RETVAL); | |
59 | rv = salsa20_keystream(&self->state, out_data, (unsigned long)out_len); | |
60 | if (rv != CRYPT_OK) { | |
61 | SvREFCNT_dec(RETVAL); | |
62 | croak("FATAL: salsa20_keystream failed: %s", error_to_string(rv)); | |
55 | if (out_len == 0) { | |
56 | RETVAL = newSVpvn("", 0); | |
57 | } | |
58 | else { | |
59 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
60 | SvPOK_only(RETVAL); | |
61 | SvCUR_set(RETVAL, out_len); | |
62 | out_data = (unsigned char *)SvPVX(RETVAL); | |
63 | rv = salsa20_keystream(&self->state, out_data, (unsigned long)out_len); | |
64 | if (rv != CRYPT_OK) { | |
65 | SvREFCNT_dec(RETVAL); | |
66 | croak("FATAL: salsa20_keystream failed: %s", error_to_string(rv)); | |
67 | } | |
63 | 68 | } |
64 | 69 | } |
65 | 70 | OUTPUT: |
78 | 83 | RETVAL = newSVpvn("", 0); |
79 | 84 | } |
80 | 85 | else { |
81 | RETVAL = NEWSV(0, in_data_len); | |
86 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
82 | 87 | SvPOK_only(RETVAL); |
83 | 88 | SvCUR_set(RETVAL, in_data_len); |
84 | 89 | out_data = (unsigned char *)SvPVX(RETVAL); |
52 | 52 | int rv; |
53 | 53 | unsigned char *out_data; |
54 | 54 | |
55 | RETVAL = NEWSV(0, out_len); | |
56 | SvPOK_only(RETVAL); | |
57 | SvCUR_set(RETVAL, out_len); | |
58 | out_data = (unsigned char *)SvPVX(RETVAL); | |
59 | rv = sober128_stream_keystream(&self->state, out_data, (unsigned long)out_len); | |
60 | if (rv != CRYPT_OK) { | |
61 | SvREFCNT_dec(RETVAL); | |
62 | croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv)); | |
55 | if (out_len == 0) { | |
56 | RETVAL = newSVpvn("", 0); | |
57 | } | |
58 | else { | |
59 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
60 | SvPOK_only(RETVAL); | |
61 | SvCUR_set(RETVAL, out_len); | |
62 | out_data = (unsigned char *)SvPVX(RETVAL); | |
63 | rv = sober128_stream_keystream(&self->state, out_data, (unsigned long)out_len); | |
64 | if (rv != CRYPT_OK) { | |
65 | SvREFCNT_dec(RETVAL); | |
66 | croak("FATAL: sober128_stream_keystream failed: %s", error_to_string(rv)); | |
67 | } | |
63 | 68 | } |
64 | 69 | } |
65 | 70 | OUTPUT: |
78 | 83 | RETVAL = newSVpvn("", 0); |
79 | 84 | } |
80 | 85 | else { |
81 | RETVAL = NEWSV(0, in_data_len); | |
86 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
82 | 87 | SvPOK_only(RETVAL); |
83 | 88 | SvCUR_set(RETVAL, in_data_len); |
84 | 89 | out_data = (unsigned char *)SvPVX(RETVAL); |
58 | 58 | int rv; |
59 | 59 | unsigned char *out_data; |
60 | 60 | |
61 | RETVAL = NEWSV(0, out_len); | |
62 | SvPOK_only(RETVAL); | |
63 | SvCUR_set(RETVAL, out_len); | |
64 | out_data = (unsigned char *)SvPVX(RETVAL); | |
65 | rv = sosemanuk_keystream(&self->state, out_data, (unsigned long)out_len); | |
66 | if (rv != CRYPT_OK) { | |
67 | SvREFCNT_dec(RETVAL); | |
68 | croak("FATAL: sosemanuk_keystream failed: %s", error_to_string(rv)); | |
61 | if (out_len == 0) { | |
62 | RETVAL = newSVpvn("", 0); | |
63 | } | |
64 | else { | |
65 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ | |
66 | SvPOK_only(RETVAL); | |
67 | SvCUR_set(RETVAL, out_len); | |
68 | out_data = (unsigned char *)SvPVX(RETVAL); | |
69 | rv = sosemanuk_keystream(&self->state, out_data, (unsigned long)out_len); | |
70 | if (rv != CRYPT_OK) { | |
71 | SvREFCNT_dec(RETVAL); | |
72 | croak("FATAL: sosemanuk_keystream failed: %s", error_to_string(rv)); | |
73 | } | |
69 | 74 | } |
70 | 75 | } |
71 | 76 | OUTPUT: |
84 | 89 | RETVAL = newSVpvn("", 0); |
85 | 90 | } |
86 | 91 | else { |
87 | RETVAL = NEWSV(0, in_data_len); | |
92 | RETVAL = NEWSV(0, in_data_len); /* avoid zero! */ | |
88 | 93 | SvPOK_only(RETVAL); |
89 | 94 | SvCUR_set(RETVAL, in_data_len); |
90 | 95 | out_data = (unsigned char *)SvPVX(RETVAL); |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | ||
15 | sub ccm_encrypt_authenticate { | |
16 | my $cipher_name = shift; | |
17 | my $key = shift; | |
18 | my $iv = shift; | |
19 | my $adata = shift; | |
20 | my $tag_len = shift; | |
21 | my $plaintext = shift; | |
22 | ||
23 | $iv = "" if !defined $iv; | |
24 | $adata = "" if !defined $adata; | |
25 | $plaintext = "" if !defined $plaintext; | |
26 | ||
27 | local $SIG{__DIE__} = \&CryptX::_croak; | |
28 | my $m = Crypt::AuthEnc::CCM->new($cipher_name, $key, $iv, $adata, $tag_len, length($plaintext)); | |
29 | my $ct = $m->encrypt_add($plaintext); | |
30 | my $tag = $m->encrypt_done(); | |
31 | return ($ct, $tag); | |
32 | } | |
33 | ||
34 | sub ccm_decrypt_verify { | |
35 | my $cipher_name = shift; | |
36 | my $key = shift; | |
37 | my $iv = shift; | |
38 | my $adata = shift; | |
39 | my $ciphertext = shift; | |
40 | my $tag = shift; | |
41 | ||
42 | $iv = "" if !defined $iv; | |
43 | $adata = "" if !defined $adata; | |
44 | $ciphertext = "" if !defined $ciphertext; | |
45 | ||
46 | local $SIG{__DIE__} = \&CryptX::_croak; | |
47 | my $m = Crypt::AuthEnc::CCM->new($cipher_name, $key, $iv, $adata, length($tag), length($ciphertext)); | |
48 | my $pt = $m->decrypt_add($ciphertext); | |
49 | return $m->decrypt_done($tag) ? $pt : undef; | |
50 | } | |
51 | 14 | |
52 | 15 | 1; |
53 | 16 |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | ||
15 | sub chacha20poly1305_encrypt_authenticate { | |
16 | my $key = shift; | |
17 | my $iv = shift; | |
18 | my $adata = shift; | |
19 | my $plaintext = shift; | |
20 | ||
21 | local $SIG{__DIE__} = \&CryptX::_croak; | |
22 | my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); | |
23 | $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string | |
24 | my $ct = $m->encrypt_add($plaintext); | |
25 | my $tag = $m->encrypt_done; | |
26 | return ($ct, $tag); | |
27 | } | |
28 | ||
29 | sub chacha20poly1305_decrypt_verify { | |
30 | my $key = shift; | |
31 | my $iv = shift; | |
32 | my $adata = shift; | |
33 | my $ciphertext = shift; | |
34 | my $tag = shift; | |
35 | ||
36 | local $SIG{__DIE__} = \&CryptX::_croak; | |
37 | my $m = Crypt::AuthEnc::ChaCha20Poly1305->new($key, $iv); | |
38 | $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string | |
39 | my $ct = $m->decrypt_add($ciphertext); | |
40 | return $m->decrypt_done($tag) ? $ct : undef; | |
41 | } | |
42 | 14 | |
43 | 15 | 1; |
44 | 16 |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | ||
15 | ### the following methods/functions are implemented in XS: | |
16 | # - new | |
17 | # - DESTROY | |
18 | # - clone | |
19 | # - encrypt_add | |
20 | # - encrypt_done | |
21 | # - decrypt_add | |
22 | # - decrypt_done | |
23 | # - adata_add | |
24 | ||
25 | sub eax_encrypt_authenticate { | |
26 | my $cipher_name = shift; | |
27 | my $key = shift; | |
28 | my $iv = shift; | |
29 | my $adata = shift; | |
30 | my $plaintext = shift; | |
31 | ||
32 | local $SIG{__DIE__} = \&CryptX::_croak; | |
33 | my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); | |
34 | $m->adata_add($adata) if defined $adata; | |
35 | my $ct = $m->encrypt_add($plaintext); | |
36 | my $tag = $m->encrypt_done; | |
37 | return ($ct, $tag); | |
38 | } | |
39 | ||
40 | sub eax_decrypt_verify { | |
41 | my $cipher_name = shift; | |
42 | my $key = shift; | |
43 | my $iv = shift; | |
44 | my $adata = shift; | |
45 | my $ciphertext = shift; | |
46 | my $tag = shift; | |
47 | ||
48 | local $SIG{__DIE__} = \&CryptX::_croak; | |
49 | my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $iv); | |
50 | $m->adata_add($adata) if defined $adata; | |
51 | my $ct = $m->decrypt_add($ciphertext); | |
52 | return $m->decrypt_done($tag) ? $ct : undef; | |
53 | } | |
54 | 14 | |
55 | 15 | # obsolete, only for backwards compatibility |
56 | 16 | sub header_add { goto &adata_add } |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | ||
15 | sub gcm_encrypt_authenticate { | |
16 | my $cipher_name = shift; | |
17 | my $key = shift; | |
18 | my $iv = shift; | |
19 | my $adata = shift; | |
20 | my $plaintext = shift; | |
21 | ||
22 | local $SIG{__DIE__} = \&CryptX::_croak; | |
23 | my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); | |
24 | $m->iv_add($iv); | |
25 | $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string | |
26 | my $ct = $m->encrypt_add($plaintext); | |
27 | my $tag = $m->encrypt_done; | |
28 | return ($ct, $tag); | |
29 | } | |
30 | ||
31 | sub gcm_decrypt_verify { | |
32 | my $cipher_name = shift; | |
33 | my $key = shift; | |
34 | my $iv = shift; | |
35 | my $adata = shift; | |
36 | my $ciphertext = shift; | |
37 | my $tag = shift; | |
38 | ||
39 | local $SIG{__DIE__} = \&CryptX::_croak; | |
40 | my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); | |
41 | $m->iv_add($iv); | |
42 | $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string | |
43 | my $ct = $m->decrypt_add($ciphertext); | |
44 | return $m->decrypt_done($tag) ? $ct : undef; | |
45 | } | |
46 | 14 | |
47 | 15 | 1; |
48 | 16 |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | ||
15 | sub ocb_encrypt_authenticate { | |
16 | my $cipher_name = shift; | |
17 | my $key = shift; | |
18 | my $nonce = shift; | |
19 | my $adata = shift; | |
20 | my $tag_len = shift; | |
21 | my $plaintext = shift; | |
22 | ||
23 | local $SIG{__DIE__} = \&CryptX::_croak; | |
24 | my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce, $tag_len); | |
25 | $m->adata_add($adata) if defined $adata; | |
26 | my $ct = $m->encrypt_last($plaintext); | |
27 | my $tag = $m->encrypt_done; | |
28 | return ($ct, $tag); | |
29 | } | |
30 | ||
31 | sub ocb_decrypt_verify { | |
32 | my $cipher_name = shift; | |
33 | my $key = shift; | |
34 | my $nonce = shift; | |
35 | my $adata = shift; | |
36 | my $ciphertext = shift; | |
37 | my $tag = shift; | |
38 | ||
39 | local $SIG{__DIE__} = \&CryptX::_croak; | |
40 | my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce, length($tag)); | |
41 | $m->adata_add($adata) if defined $adata; | |
42 | my $ct = $m->decrypt_last($ciphertext); | |
43 | return $m->decrypt_done($tag) ? $ct : undef; | |
44 | } | |
45 | 14 | |
46 | 15 | # obsolete, only for backwards compatibility |
47 | 16 | sub aad_add { goto &adata_add } |
11 | 11 | use Carp; |
12 | 12 | $Carp::Internal{(__PACKAGE__)}++; |
13 | 13 | use CryptX; |
14 | use Crypt::Digest; | |
15 | ||
16 | sub pbkdf1 { | |
17 | my ($password, $salt, $iteration_count, $hash_name, $len) = @_; | |
18 | $iteration_count ||= 5000; | |
19 | $hash_name ||= 'SHA256'; | |
20 | $len ||= 32; | |
21 | local $SIG{__DIE__} = \&CryptX::_croak; | |
22 | return _pkcs_5_alg1($password, $salt, $iteration_count, $hash_name, $len); | |
23 | } | |
24 | ||
25 | sub pbkdf2 { | |
26 | my ($password, $salt, $iteration_count, $hash_name, $len) = @_; | |
27 | $iteration_count ||= 5000; | |
28 | $hash_name ||= 'SHA256'; | |
29 | $len ||= 32; | |
30 | local $SIG{__DIE__} = \&CryptX::_croak; | |
31 | return _pkcs_5_alg2($password, $salt, $iteration_count, $hash_name, $len); | |
32 | } | |
33 | ||
34 | sub hkdf_extract { | |
35 | # RFC: HKDF-Extract(salt, IKM, [Hash]) -> PRK | |
36 | #my ($hash_name, $salt, $keying_material) = @_; | |
37 | my ($keying_material, $salt, $hash_name) = @_; | |
38 | $hash_name ||= 'SHA256'; | |
39 | $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets | |
40 | local $SIG{__DIE__} = \&CryptX::_croak; | |
41 | return _hkdf_extract($hash_name, $salt, $keying_material); | |
42 | } | |
43 | ||
44 | sub hkdf_expand { | |
45 | # RFC: HKDF-Expand(PRK, info, L, [Hash]) -> OKM | |
46 | #my ($hash_name, $info, $keying_material, $len) = @_; | |
47 | my ($keying_material, $hash_name, $len, $info) = @_; | |
48 | $len ||= 32; | |
49 | $info ||= ''; | |
50 | $hash_name ||= 'SHA256'; | |
51 | local $SIG{__DIE__} = \&CryptX::_croak; | |
52 | return _hkdf_expand($hash_name, $info, $keying_material, $len); | |
53 | } | |
54 | ||
55 | sub hkdf { | |
56 | #my ($hash_name, $salt, $info, $keying_material, $len) = @_; | |
57 | my ($keying_material, $salt, $hash_name, $len, $info) = @_; | |
58 | $len ||= 32; | |
59 | $info ||= ''; | |
60 | $hash_name ||= 'SHA256'; | |
61 | $salt = pack("H*", "00" x Crypt::Digest->hashsize($hash_name)) unless defined $salt; # according to rfc5869 defaults to HashLen zero octets | |
62 | local $SIG{__DIE__} = \&CryptX::_croak; | |
63 | return _hkdf($hash_name, $salt, $info, $keying_material, $len); | |
64 | } | |
65 | 14 | |
66 | 15 | 1; |
67 | 16 |
94 | 94 | croak "FATAL: invalid or unsupported DSA key format"; |
95 | 95 | } |
96 | 96 | |
97 | sub sign_message { | |
98 | my ($self, $data, $hash_name) = @_; | |
99 | $hash_name ||= 'SHA1'; | |
100 | return $self->sign_hash(digest_data($hash_name, $data)); | |
101 | } | |
102 | ||
103 | sub verify_message { | |
104 | my ($self, $sig, $data, $hash_name) = @_; | |
105 | return $self->verify_hash($sig, digest_data($hash_name||'SHA1', $data)); | |
106 | } | |
107 | ||
108 | 97 | ### FUNCTIONS |
109 | 98 | |
110 | 99 | sub dsa_encrypt { |
565 | 565 | croak "FATAL: invalid or unsupported EC key format"; |
566 | 566 | } |
567 | 567 | |
568 | sub encrypt { | |
569 | my ($self, $data, $hash_name) = @_; | |
570 | $hash_name ||= 'SHA1'; | |
571 | return $self->_encrypt($data, $hash_name); | |
572 | } | |
573 | ||
574 | sub decrypt { | |
575 | my ($self, $data) = @_; | |
576 | return $self->_decrypt($data); | |
577 | } | |
578 | ||
579 | sub sign_message { | |
580 | my ($self, $data, $hash_name) = @_; | |
581 | $hash_name ||= 'SHA1'; | |
582 | my $data_hash = digest_data($hash_name, $data); | |
583 | return $self->_sign($data_hash); | |
584 | } | |
585 | ||
586 | sub sign_message_rfc7518 { | |
587 | my ($self, $data, $hash_name) = @_; | |
588 | $hash_name ||= 'SHA1'; | |
589 | my $data_hash = digest_data($hash_name, $data); | |
590 | return $self->_sign_rfc7518($data_hash); | |
591 | } | |
592 | ||
593 | sub verify_message { | |
594 | my ($self, $sig, $data, $hash_name) = @_; | |
595 | $hash_name ||= 'SHA1'; | |
596 | my $data_hash = digest_data($hash_name, $data); | |
597 | return $self->_verify($sig, $data_hash); | |
598 | } | |
599 | ||
600 | sub verify_message_rfc7518 { | |
601 | my ($self, $sig, $data, $hash_name) = @_; | |
602 | $hash_name ||= 'SHA1'; | |
603 | my $data_hash = digest_data($hash_name, $data); | |
604 | return $self->_verify_rfc7518($sig, $data_hash); | |
605 | } | |
606 | ||
607 | sub sign_hash { | |
608 | my ($self, $data_hash) = @_; | |
609 | return $self->_sign($data_hash); | |
610 | } | |
611 | ||
612 | sub verify_hash { | |
613 | my ($self, $sig, $data_hash) = @_; | |
614 | return $self->_verify($sig, $data_hash); | |
615 | } | |
616 | ||
617 | 568 | sub curve2hash { |
618 | 569 | my $self = shift; |
619 | 570 | my $kh = $self->key2hash; |
624 | 575 | Gx => $kh->{curve_Gx}, |
625 | 576 | Gy => $kh->{curve_Gy}, |
626 | 577 | cofactor => $kh->{curve_cofactor}, |
627 | order => $kh->{curve_order} | |
578 | order => $kh->{curve_order}, | |
579 | oid => $kh->{curve_oid}, | |
628 | 580 | }; |
629 | 581 | } |
630 | 582 |
162 | 162 | croak "FATAL: invalid or unsupported RSA key format"; |
163 | 163 | } |
164 | 164 | |
165 | sub sign_message { | |
166 | my ($self, $data, $hash_name, $padding, $saltlen) = @_; | |
167 | $saltlen ||= 12; | |
168 | $padding ||= 'pss'; | |
169 | $hash_name ||= 'SHA1'; | |
170 | return $self->sign_hash(digest_data($hash_name, $data), $hash_name, $padding, $saltlen); | |
171 | } | |
172 | ||
173 | sub verify_message { | |
174 | my ($self, $sig, $data, $hash_name, $padding, $saltlen) = @_; | |
175 | $saltlen ||= 12; | |
176 | $padding ||= 'pss'; | |
177 | $hash_name ||= 'SHA1'; | |
178 | return $self->verify_hash($sig, digest_data($hash_name, $data), $hash_name, $padding, $saltlen); | |
179 | } | |
180 | ||
181 | 165 | ### FUNCTIONS |
182 | 166 | |
183 | 167 | sub rsa_encrypt { |
0 | 0 | use strict; |
1 | 1 | use warnings; |
2 | 2 | |
3 | use Test::More tests => 12; | |
3 | use Test::More tests => 13; | |
4 | 4 | |
5 | 5 | use Crypt::AuthEnc::CCM qw( ccm_encrypt_authenticate ccm_decrypt_verify ); |
6 | 6 | |
44 | 44 | } |
45 | 45 | |
46 | 46 | { |
47 | my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "", 16, "plain_halfplain_half"); | |
47 | my ($ct, $tag) = ccm_encrypt_authenticate('AES', $key, $nonce, "", 16, "plain_halfplain_half"); | |
48 | my ($ct2, $tag2) = ccm_encrypt_authenticate('AES', $key, $nonce, undef, 16, "plain_halfplain_half"); | |
49 | ok($ct eq $ct2 && $tag eq $tag2, "header '' vs. undef"); | |
48 | 50 | is(unpack('H*', $ct), "96b0114ff47da72e92631aadce84f203a8168b20", "ccm_encrypt_authenticate: ciphertext (no header)"); |
49 | 51 | is(unpack('H*', $tag), "9e9cba5dd4939d0d8e2687c85c5d3b89", "ccm_encrypt_authenticate: tag (no header)"); |
50 | 52 | my $pt = ccm_decrypt_verify('AES', $key, $nonce, "", $ct, $tag); |