Codebase list libcryptx-perl / 71c5bc4
moving more code to XS Karel Miko 6 years ago
47 changed file(s) with 893 addition(s) and 741 deletion(s). Raw diff Collapse all Expand all
280280 return CRYPT_OK;
281281 }
282282
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)
284284 {
285285 size_t i, start = 0;
286286 if (name == NULL || strlen(name) + 1 > ltclen) croak("FATAL: invalid name") ;
432432 }
433433 else {
434434 out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1);
435 RETVAL = NEWSV(0, out_len);
435 RETVAL = NEWSV(0, out_len); /* avoid zero! */
436436 SvPOK_only(RETVAL);
437437 out_data = (unsigned char *)SvPVX(RETVAL);
438438 if (base64url_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) {
460460 }
461461 else {
462462 out_len = (unsigned long)in_len;
463 RETVAL = NEWSV(0, out_len);
463 RETVAL = NEWSV(0, out_len); /* avoid zero! */
464464 SvPOK_only(RETVAL);
465465 out_data = (unsigned char *)SvPVX(RETVAL);
466466 if (base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) {
488488 }
489489 else {
490490 out_len = (unsigned long)(4 * ((in_len + 2) / 3) + 1);
491 RETVAL = NEWSV(0, out_len);
491 RETVAL = NEWSV(0, out_len); /* avoid zero! */
492492 SvPOK_only(RETVAL);
493493 out_data = (unsigned char *)SvPVX(RETVAL);
494494 if (base64_encode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) {
516516 }
517517 else {
518518 out_len = (unsigned long)in_len;
519 RETVAL = NEWSV(0, out_len);
519 RETVAL = NEWSV(0, out_len); /* avoid zero! */
520520 SvPOK_only(RETVAL);
521521 out_data = (unsigned char *)SvPVX(RETVAL);
522522 if (base64_decode(in_data, (unsigned long)in_len, out_data, &out_len) != CRYPT_OK) {
550550 }
551551 else {
552552 out_len = (unsigned long)((8 * in_len + 4) / 5);
553 RETVAL = NEWSV(0, out_len);
553 RETVAL = NEWSV(0, out_len); /* avoid zero! */
554554 SvPOK_only(RETVAL);
555555 out_data = (unsigned char *)SvPVX(RETVAL);
556556 if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) {
584584 }
585585 else {
586586 out_len = (unsigned long)in_len;
587 RETVAL = NEWSV(0, out_len);
587 RETVAL = NEWSV(0, out_len); /* avoid zero! */
588588 SvPOK_only(RETVAL);
589589 out_data = (unsigned char *)SvPVX(RETVAL);
590590 if (base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) {
606606
607607 if (!SvPOK(in)) XSRETURN_UNDEF;
608608 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 }
624627 }
625628 }
626629 OUTPUT:
635638
636639 if (!SvPOK(in)) XSRETURN_UNDEF;
637640 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 }
653659 }
654660 }
655661 OUTPUT:
663669 unsigned char *out_data;
664670 mp_int mpi;
665671
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) {
670678 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);
681694 }
682695 OUTPUT:
683696 RETVAL
695708
696709 if (!SvPOK(in) || radix < 2 || radix > 64) XSRETURN_UNDEF;
697710 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 }
712732 }
713733 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);
726738 }
727739 OUTPUT:
728740 RETVAL
3030 if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
3131 [%-END%]
3232
33 LTC_UNUSED_PARAM(class);
3334 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
3435 k = (unsigned char *) SvPVbyte(key, k_len);
3536
130131 RETVAL = newSVpvn(out, outlen);
131132 }
132133 else {
133 RETVAL = newSVpvn(mac, maclen);
134 RETVAL = newSVpvn((char * )mac, maclen);
134135 }
135136 }
136137 OUTPUT:
168169 [%-IF lc_name == 'hmac' %]
169170 int id = _find_hash(hash_name);
170171 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);
172173 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv));
173174 for (i = 2; i < items; i++) {
174175 in = (unsigned char *)SvPVbyte(ST(i), inlen);
175176 if (inlen > 0) {
176 rv = [%lc_name%]_process(&st, in, inlen);
177 rv = [%lc_name%]_process(&st, in, (unsigned long)inlen);
177178 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv));
178179 }
179180 }
181182 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv));
182183 [%-ELSIF lc_name == 'blake2s' || lc_name == 'blake2b' %]
183184 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);
185186 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_init failed: %s", error_to_string(rv));
186187 for (i = 2; i < items; i++) {
187188 in = (unsigned char *)SvPVbyte(ST(i), inlen);
188189 if (inlen > 0) {
189 rv = [%lc_name%]mac_process(&st, in, inlen);
190 rv = [%lc_name%]mac_process(&st, in, (unsigned long)inlen);
190191 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_process failed: %s", error_to_string(rv));
191192 }
192193 }
194195 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]mac_done failed: %s", error_to_string(rv));
195196 [%-ELSIF lc_name == 'pelican' %]
196197 len = 16;
197 rv = [%lc_name%]_init(&st, k, klen);
198 rv = [%lc_name%]_init(&st, k, (unsigned long)klen);
198199 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv));
199200 for (i = 1; i < items; i++) {
200201 in = (unsigned char *)SvPVbyte(ST(i), inlen);
201202 if (inlen > 0) {
202 rv = [%lc_name%]_process(&st, in, inlen);
203 rv = [%lc_name%]_process(&st, in, (unsigned long)inlen);
203204 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv));
204205 }
205206 }
206207 rv = [%lc_name%]_done(&st, mac);
207208 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_done failed: %s", error_to_string(rv));
208209 [%-ELSIF lc_name == 'poly1305' %]
209 rv = [%lc_name%]_init(&st, k, klen);
210 rv = [%lc_name%]_init(&st, k, (unsigned long)klen);
210211 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv));
211212 for (i = 1; i < items; i++) {
212213 in = (unsigned char *)SvPVbyte(ST(i), inlen);
213214 if (inlen > 0) {
214 rv = [%lc_name%]_process(&st, in, inlen);
215 rv = [%lc_name%]_process(&st, in, (unsigned long)inlen);
215216 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv));
216217 }
217218 }
220221 [%-ELSE%]
221222 int id = _find_cipher(cipher_name);
222223 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);
224225 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_init failed: %s", error_to_string(rv));
225226 for (i = 2; i < items; i++) {
226227 in = (unsigned char *)SvPVbyte(ST(i), inlen);
227228 if (inlen > 0) {
228 rv = [%lc_name%]_process(&st, in, inlen);
229 rv = [%lc_name%]_process(&st, in, (unsigned long)inlen);
229230 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_process failed: %s", error_to_string(rv));
230231 }
231232 }
99 [%-END%]
1010 CODE:
1111 {
12 LTC_UNUSED_PARAM(class);
1213 Newz(0, RETVAL, 1, struct [%lc_name%]_struct);
1314 if (!RETVAL) croak("FATAL: Newz failed");
1415 RETVAL->direction = 0;
3637
3738 void
3839 [%-IF lc_name == 'xts' %]
39 _start(_XXX_XXX_XXX_)
40 start_decrypt(_XXX_XXX_XXX_)
4041 [%-ELSIF lc_name == 'f8' %]
41 _start(_XXX_XXX_XXX_)
42 start_decrypt(_XXX_XXX_XXX_)
4243 [%-ELSIF lc_name == 'lrw' %]
43 _start(_XXX_XXX_XXX_)
44 start_decrypt(_XXX_XXX_XXX_)
4445 [%-ELSE%]
45 _start(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv)
46 start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key, SV * iv)
4647 [%-END%]
4748 ALIAS:
4849 start_encrypt = 1
49 start_decrypt = 2
5050 PPCODE:
5151 {
5252 STRLEN k_len=0;
9696 RETVAL = newSVpvn("", 0);
9797 }
9898 else {
99 RETVAL = NEWSV(0, in_data_len);
99 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
100100 SvPOK_only(RETVAL);
101101 SvCUR_set(RETVAL, in_data_len);
102102 out_data = (unsigned char *)SvPVX(RETVAL);
55 new(char * class, char * cipher_name, int padding=1, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct [%lc_name%]_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->padding_mode = padding;
2728
2829 void
2930 [%-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)
3132 [%-ELSIF lc_name == 'ecb' %]
32 _start(Crypt::Mode::[%orig_name%] self, SV * key)
33 start_decrypt(Crypt::Mode::[%orig_name%] self, SV * key)
3334 [%-ELSE%]
34 _start(_XXX_XXX_XXX_)
35 start_decrypt(_XXX_XXX_XXX_)
3536 [%-END%]
3637 ALIAS:
3738 start_encrypt = 1
38 start_decrypt = 2
3939 PPCODE:
4040 {
4141 int rv;
113113
114114 if (in_data_len > 0) {
115115 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! */
117117 SvPOK_only(RETVAL);
118118 SvCUR_set(RETVAL, i);
119119 out_data = (unsigned char *)SvPVX(RETVAL);
194194 RETVAL = newSVpvn("", 0);
195195 }
196196 else {
197 RETVAL = NEWSV(0, i);
197 RETVAL = NEWSV(0, i); /* avoid zero! */
198198 SvPOK_only(RETVAL);
199199 SvCUR_set(RETVAL, i);
200200 out_data = (unsigned char *)SvPVX(RETVAL);
1010 unsigned char *h=NULL;
1111 STRLEN h_len=0;
1212 int rv, id;
13 LTC_UNUSED_PARAM(class);
1314
1415 if (tag_len < 1 || tag_len > MAXBLOCKSIZE) croak("FATAL: invalid tag_len %d", tag_len);
1516 if (pt_len < 0) croak("FATAL: invalid pt_len");
8081 croak("FATAL: encrypt_add failed: wrong direction");
8182 }
8283 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! */
8485 SvPOK_only(RETVAL);
8586 SvCUR_set(RETVAL, in_data_len);
8687 out_data = (unsigned char *)SvPVX(RETVAL);
113114 croak("FATAL: decrypt_add failed: wrong direction");
114115 }
115116 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! */
117118 SvPOK_only(RETVAL);
118119 SvCUR_set(RETVAL, in_data_len);
119120 out_data = (unsigned char *)SvPVX(RETVAL);
178179 }
179180 }
180181 }
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 }
66 int rv;
77 STRLEN iv_len=0, k_len=0;
88 unsigned char *iv=NULL, *k=NULL;
9 LTC_UNUSED_PARAM(class);
910
1011 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1112 k = (unsigned char *) SvPVbyte(key, k_len);
105106 RETVAL = newSVpvn("", 0);
106107 }
107108 else {
108 RETVAL = NEWSV(0, in_data_len);
109 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
109110 SvPOK_only(RETVAL);
110111 SvCUR_set(RETVAL, in_data_len);
111112 out_data = (unsigned char *)SvPVX(RETVAL);
132133 RETVAL = newSVpvn("", 0);
133134 }
134135 else {
135 RETVAL = NEWSV(0, in_data_len);
136 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
136137 SvPOK_only(RETVAL);
137138 SvCUR_set(RETVAL, in_data_len);
138139 out_data = (unsigned char *)SvPVX(RETVAL);
188189 }
189190 }
190191 }
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 }
1010 unsigned char *h=NULL;
1111 STRLEN h_len=0;
1212 int rv, id;
13 LTC_UNUSED_PARAM(class);
1314
1415 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1516 k = (unsigned char *) SvPVbyte(key, k_len);
6263 RETVAL = newSVpvn("", 0);
6364 }
6465 else {
65 RETVAL = NEWSV(0, in_data_len);
66 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
6667 SvPOK_only(RETVAL);
6768 SvCUR_set(RETVAL, in_data_len);
6869 out_data = (unsigned char *)SvPVX(RETVAL);
8990 RETVAL = newSVpvn("", 0);
9091 }
9192 else {
92 RETVAL = NEWSV(0, in_data_len);
93 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
9394 SvPOK_only(RETVAL);
9495 SvCUR_set(RETVAL, in_data_len);
9596 out_data = (unsigned char *)SvPVX(RETVAL);
158159 if (rv != CRYPT_OK) croak("FATAL: eax_addheader failed: %s", error_to_string(rv));
159160 XPUSHs(ST(0)); /* return self */
160161 }
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 }
66 STRLEN k_len = 0, iv_len = 0;
77 unsigned char *k = NULL, *iv = NULL;
88 int id, rv;
9 LTC_UNUSED_PARAM(class);
910
1011 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1112 k = (unsigned char *) SvPVbyte(key, k_len);
7576 }
7677 else
7778 {
78 RETVAL = NEWSV(0, in_data_len);
79 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
7980 SvPOK_only(RETVAL);
8081 SvCUR_set(RETVAL, in_data_len);
8182 out_data = (unsigned char *)SvPVX(RETVAL);
130131 RETVAL = newSVpvn("", 0);
131132 }
132133 else {
133 RETVAL = NEWSV(0, in_data_len);
134 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
134135 SvPOK_only(RETVAL);
135136 SvCUR_set(RETVAL, in_data_len);
136137 out_data = (unsigned char *)SvPVX(RETVAL);
187188 }
188189 }
189190 }
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 }
88 unsigned char *n=NULL;
99 STRLEN n_len=0;
1010 int rv, id;
11 LTC_UNUSED_PARAM(class);
1112
1213 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1314 k = (unsigned char *) SvPVbyte(key, k_len);
7677 if (in_data_len % 16) {
7778 croak ("FATAL: sizeof(data) should be multiple of 16");
7879 }
79 RETVAL = NEWSV(0, in_data_len);
80 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
8081 SvPOK_only(RETVAL);
8182 SvCUR_set(RETVAL, in_data_len);
8283 out_data = (unsigned char *)SvPVX(RETVAL);
107108 RETVAL = newSVpvn("", 0);
108109 }
109110 else {
110 RETVAL = NEWSV(0, in_data_len);
111 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
111112 SvPOK_only(RETVAL);
112113 SvCUR_set(RETVAL, in_data_len);
113114 out_data = (unsigned char *)SvPVX(RETVAL);
137138 if (in_data_len % 16) {
138139 croak ("FATAL: sizeof(data) should be multiple of 16");
139140 }
140 RETVAL = NEWSV(0, in_data_len);
141 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
141142 SvPOK_only(RETVAL);
142143 SvCUR_set(RETVAL, in_data_len);
143144 out_data = (unsigned char *)SvPVX(RETVAL);
168169 RETVAL = newSVpvn("", 0);
169170 }
170171 else {
171 RETVAL = NEWSV(0, in_data_len);
172 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
172173 SvPOK_only(RETVAL);
173174 SvCUR_set(RETVAL, in_data_len);
174175 out_data = (unsigned char *)SvPVX(RETVAL);
225226 }
226227 }
227228 }
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 }
5656 RETVAL = newSVpvn("", 0);
5757 }
5858 else if (len == (STRLEN)self->desc->block_length) {
59 RETVAL = NEWSV(0, len);
59 RETVAL = NEWSV(0, len); /* avoid zero! */
6060 SvPOK_only(RETVAL);
6161 SvCUR_set(RETVAL, len);
6262 rv = self->desc->ecb_encrypt((unsigned char *)plaintext, (unsigned char *)SvPVX(RETVAL), &self->skey);
8484 RETVAL = newSVpvn("", 0);
8585 }
8686 else if (len == (STRLEN)self->desc->block_length) {
87 RETVAL = NEWSV(0, len);
87 RETVAL = NEWSV(0, len); /* avoid zero! */
8888 SvPOK_only(RETVAL);
8989 SvCUR_set(RETVAL, len);
9090 rv = self->desc->ecb_decrypt((unsigned char *)ciphertext, (unsigned char *)SvPVX(RETVAL), &self->skey);
44 CODE:
55 {
66 int rv;
7 LTC_UNUSED_PARAM(class);
78
89 Newz(0, RETVAL, 1, struct digest_shake_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
6768 int rv;
6869 unsigned char *out_data;
6970
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 }
7884 }
7985 }
8086 OUTPUT:
00 MODULE = CryptX PACKAGE = Crypt::KeyDerivation
11
22 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)
44 CODE:
55 {
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 */
126 int rv, id;
137 unsigned char *output;
148 unsigned char *password_ptr=NULL;
1610 unsigned char *salt_ptr=NULL;
1711 STRLEN salt_len=0;
1812
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);
2119
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");
2523
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);
3028
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);
3535 }
36 SvCUR_set(RETVAL, output_len);
3736 }
3837 OUTPUT:
3938 RETVAL
4039
4140 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)
4342 CODE:
4443 {
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 */
5144 int rv, id;
5245 unsigned char *output;
5346 unsigned char *password_ptr=NULL;
5548 unsigned char *salt_ptr=NULL;
5649 STRLEN salt_len=0;
5750
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);
6057
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);
6360
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);
6865
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);
7372 }
74 SvCUR_set(RETVAL, output_len);
7573 }
7674 OUTPUT:
7775 RETVAL
7876
7977 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")
8179 CODE:
8280 {
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 */
8881 int rv, id;
8982 unsigned char output[MAXBLOCKSIZE];
9083 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;
9586
9687 id = _find_hash(hash_name);
9788 if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name);
9889
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);
10192
10293 output_len = sizeof(output);
10394 rv = hkdf_extract(id, salt_ptr, (unsigned long)salt_len, in_ptr, (unsigned long)in_len, output, &output_len);
109100 RETVAL
110101
111102 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)
113104 CODE:
114105 {
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 */
120106 int rv, id;
121107 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;
126110
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);
129117
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);
132120
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);
137125
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);
142132 }
143 SvCUR_set(RETVAL, output_len);
144133 }
145134 OUTPUT:
146135 RETVAL
147136
148137 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)
150139 CODE:
151140 {
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 */
158141 int rv, id;
159142 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;
166145
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);
169152
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);
173156
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);
178161
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);
183168 }
184 SvCUR_set(RETVAL, output_len);
185169 }
186170 OUTPUT:
187171 RETVAL
99 unsigned char *k=NULL;
1010 int rv;
1111
12 LTC_UNUSED_PARAM(class);
1213 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1314 k = (unsigned char *) SvPVbyte(key, k_len);
1415
8990 RETVAL = newSVpvn(out, outlen);
9091 }
9192 else {
92 RETVAL = newSVpvn(mac, maclen);
93 RETVAL = newSVpvn((char * )mac, maclen);
9394 }
9495 }
9596 OUTPUT:
113114 blake2bmac_state st;
114115
115116 if (size < len) len = size;
116 rv = blake2bmac_init(&st, len, k, klen);
117 rv = blake2bmac_init(&st, len, k, (unsigned long)klen);
117118 if (rv != CRYPT_OK) croak("FATAL: blake2bmac_init failed: %s", error_to_string(rv));
118119 for (i = 2; i < items; i++) {
119120 in = (unsigned char *)SvPVbyte(ST(i), inlen);
120121 if (inlen > 0) {
121 rv = blake2bmac_process(&st, in, inlen);
122 rv = blake2bmac_process(&st, in, (unsigned long)inlen);
122123 if (rv != CRYPT_OK) croak("FATAL: blake2bmac_process failed: %s", error_to_string(rv));
123124 }
124125 }
99 unsigned char *k=NULL;
1010 int rv;
1111
12 LTC_UNUSED_PARAM(class);
1213 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1314 k = (unsigned char *) SvPVbyte(key, k_len);
1415
8990 RETVAL = newSVpvn(out, outlen);
9091 }
9192 else {
92 RETVAL = newSVpvn(mac, maclen);
93 RETVAL = newSVpvn((char * )mac, maclen);
9394 }
9495 }
9596 OUTPUT:
113114 blake2smac_state st;
114115
115116 if (size < len) len = size;
116 rv = blake2smac_init(&st, len, k, klen);
117 rv = blake2smac_init(&st, len, k, (unsigned long)klen);
117118 if (rv != CRYPT_OK) croak("FATAL: blake2smac_init failed: %s", error_to_string(rv));
118119 for (i = 2; i < items; i++) {
119120 in = (unsigned char *)SvPVbyte(ST(i), inlen);
120121 if (inlen > 0) {
121 rv = blake2smac_process(&st, in, inlen);
122 rv = blake2smac_process(&st, in, (unsigned long)inlen);
122123 if (rv != CRYPT_OK) croak("FATAL: blake2smac_process failed: %s", error_to_string(rv));
123124 }
124125 }
1313 id = _find_cipher(cipher_name);
1414 if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
1515
16 LTC_UNUSED_PARAM(class);
1617 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1718 k = (unsigned char *) SvPVbyte(key, k_len);
1819
9394 RETVAL = newSVpvn(out, outlen);
9495 }
9596 else {
96 RETVAL = newSVpvn(mac, maclen);
97 RETVAL = newSVpvn((char * )mac, maclen);
9798 }
9899 }
99100 OUTPUT:
118119
119120 int id = _find_cipher(cipher_name);
120121 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);
122123 if (rv != CRYPT_OK) croak("FATAL: f9_init failed: %s", error_to_string(rv));
123124 for (i = 2; i < items; i++) {
124125 in = (unsigned char *)SvPVbyte(ST(i), inlen);
125126 if (inlen > 0) {
126 rv = f9_process(&st, in, inlen);
127 rv = f9_process(&st, in, (unsigned long)inlen);
127128 if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv));
128129 }
129130 }
1313 id = _find_hash(hash_name);
1414 if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name);
1515
16 LTC_UNUSED_PARAM(class);
1617 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1718 k = (unsigned char *) SvPVbyte(key, k_len);
1819
9394 RETVAL = newSVpvn(out, outlen);
9495 }
9596 else {
96 RETVAL = newSVpvn(mac, maclen);
97 RETVAL = newSVpvn((char * )mac, maclen);
9798 }
9899 }
99100 OUTPUT:
118119
119120 int id = _find_hash(hash_name);
120121 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);
122123 if (rv != CRYPT_OK) croak("FATAL: hmac_init failed: %s", error_to_string(rv));
123124 for (i = 2; i < items; i++) {
124125 in = (unsigned char *)SvPVbyte(ST(i), inlen);
125126 if (inlen > 0) {
126 rv = hmac_process(&st, in, inlen);
127 rv = hmac_process(&st, in, (unsigned long)inlen);
127128 if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv));
128129 }
129130 }
1313 id = _find_cipher(cipher_name);
1414 if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
1515
16 LTC_UNUSED_PARAM(class);
1617 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1718 k = (unsigned char *) SvPVbyte(key, k_len);
1819
9394 RETVAL = newSVpvn(out, outlen);
9495 }
9596 else {
96 RETVAL = newSVpvn(mac, maclen);
97 RETVAL = newSVpvn((char * )mac, maclen);
9798 }
9899 }
99100 OUTPUT:
118119
119120 int id = _find_cipher(cipher_name);
120121 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);
122123 if (rv != CRYPT_OK) croak("FATAL: omac_init failed: %s", error_to_string(rv));
123124 for (i = 2; i < items; i++) {
124125 in = (unsigned char *)SvPVbyte(ST(i), inlen);
125126 if (inlen > 0) {
126 rv = omac_process(&st, in, inlen);
127 rv = omac_process(&st, in, (unsigned long)inlen);
127128 if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv));
128129 }
129130 }
1313 id = _find_cipher(cipher_name);
1414 if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
1515
16 LTC_UNUSED_PARAM(class);
1617 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1718 k = (unsigned char *) SvPVbyte(key, k_len);
1819
9394 RETVAL = newSVpvn(out, outlen);
9495 }
9596 else {
96 RETVAL = newSVpvn(mac, maclen);
97 RETVAL = newSVpvn((char * )mac, maclen);
9798 }
9899 }
99100 OUTPUT:
118119
119120 int id = _find_cipher(cipher_name);
120121 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);
122123 if (rv != CRYPT_OK) croak("FATAL: pmac_init failed: %s", error_to_string(rv));
123124 for (i = 2; i < items; i++) {
124125 in = (unsigned char *)SvPVbyte(ST(i), inlen);
125126 if (inlen > 0) {
126 rv = pmac_process(&st, in, inlen);
127 rv = pmac_process(&st, in, (unsigned long)inlen);
127128 if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv));
128129 }
129130 }
99 unsigned char *k=NULL;
1010 int rv;
1111
12 LTC_UNUSED_PARAM(class);
1213 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1314 k = (unsigned char *) SvPVbyte(key, k_len);
1415
8990 RETVAL = newSVpvn(out, outlen);
9091 }
9192 else {
92 RETVAL = newSVpvn(mac, maclen);
93 RETVAL = newSVpvn((char * )mac, maclen);
9394 }
9495 }
9596 OUTPUT:
113114 pelican_state st;
114115
115116 len = 16;
116 rv = pelican_init(&st, k, klen);
117 rv = pelican_init(&st, k, (unsigned long)klen);
117118 if (rv != CRYPT_OK) croak("FATAL: pelican_init failed: %s", error_to_string(rv));
118119 for (i = 1; i < items; i++) {
119120 in = (unsigned char *)SvPVbyte(ST(i), inlen);
120121 if (inlen > 0) {
121 rv = pelican_process(&st, in, inlen);
122 rv = pelican_process(&st, in, (unsigned long)inlen);
122123 if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv));
123124 }
124125 }
99 unsigned char *k=NULL;
1010 int rv;
1111
12 LTC_UNUSED_PARAM(class);
1213 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1314 k = (unsigned char *) SvPVbyte(key, k_len);
1415
8990 RETVAL = newSVpvn(out, outlen);
9091 }
9192 else {
92 RETVAL = newSVpvn(mac, maclen);
93 RETVAL = newSVpvn((char * )mac, maclen);
9394 }
9495 }
9596 OUTPUT:
112113 char out[MAXBLOCKSIZE*2];
113114 poly1305_state st;
114115
115 rv = poly1305_init(&st, k, klen);
116 rv = poly1305_init(&st, k, (unsigned long)klen);
116117 if (rv != CRYPT_OK) croak("FATAL: poly1305_init failed: %s", error_to_string(rv));
117118 for (i = 1; i < items; i++) {
118119 in = (unsigned char *)SvPVbyte(ST(i), inlen);
119120 if (inlen > 0) {
120 rv = poly1305_process(&st, in, inlen);
121 rv = poly1305_process(&st, in, (unsigned long)inlen);
121122 if (rv != CRYPT_OK) croak("FATAL: poly1305_process failed: %s", error_to_string(rv));
122123 }
123124 }
1313 id = _find_cipher(cipher_name);
1414 if (id == -1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
1515
16 LTC_UNUSED_PARAM(class);
1617 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
1718 k = (unsigned char *) SvPVbyte(key, k_len);
1819
9394 RETVAL = newSVpvn(out, outlen);
9495 }
9596 else {
96 RETVAL = newSVpvn(mac, maclen);
97 RETVAL = newSVpvn((char * )mac, maclen);
9798 }
9899 }
99100 OUTPUT:
118119
119120 int id = _find_cipher(cipher_name);
120121 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);
122123 if (rv != CRYPT_OK) croak("FATAL: xcbc_init failed: %s", error_to_string(rv));
123124 for (i = 2; i < items; i++) {
124125 in = (unsigned char *)SvPVbyte(ST(i), inlen);
125126 if (inlen > 0) {
126 rv = xcbc_process(&st, in, inlen);
127 rv = xcbc_process(&st, in, (unsigned long)inlen);
127128 if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv));
128129 }
129130 }
55 new(char * class, char * cipher_name, int padding=1, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct cbc_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->padding_mode = padding;
2627 Safefree(self);
2728
2829 void
29 _start(Crypt::Mode::CBC self, SV * key, SV * iv)
30 start_decrypt(Crypt::Mode::CBC self, SV * key, SV * iv)
3031 ALIAS:
3132 start_encrypt = 1
32 start_decrypt = 2
3333 PPCODE:
3434 {
3535 int rv;
101101
102102 if (in_data_len > 0) {
103103 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! */
105105 SvPOK_only(RETVAL);
106106 SvCUR_set(RETVAL, i);
107107 out_data = (unsigned char *)SvPVX(RETVAL);
182182 RETVAL = newSVpvn("", 0);
183183 }
184184 else {
185 RETVAL = NEWSV(0, i);
185 RETVAL = NEWSV(0, i); /* avoid zero! */
186186 SvPOK_only(RETVAL);
187187 SvCUR_set(RETVAL, i);
188188 out_data = (unsigned char *)SvPVX(RETVAL);
55 new(char * class, char * cipher_name, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct cfb_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->direction = 0;
2425 Safefree(self);
2526
2627 void
27 _start(Crypt::Mode::CFB self, SV * key, SV * iv)
28 start_decrypt(Crypt::Mode::CFB self, SV * key, SV * iv)
2829 ALIAS:
2930 start_encrypt = 1
30 start_decrypt = 2
3131 PPCODE:
3232 {
3333 STRLEN k_len=0;
6767 RETVAL = newSVpvn("", 0);
6868 }
6969 else {
70 RETVAL = NEWSV(0, in_data_len);
70 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
7171 SvPOK_only(RETVAL);
7272 SvCUR_set(RETVAL, in_data_len);
7373 out_data = (unsigned char *)SvPVX(RETVAL);
55 new(char * class, char * cipher_name, int ctr_mode=0, int ctr_width=0, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct ctr_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->direction = 0;
2930 Safefree(self);
3031
3132 void
32 _start(Crypt::Mode::CTR self, SV * key, SV * iv)
33 start_decrypt(Crypt::Mode::CTR self, SV * key, SV * iv)
3334 ALIAS:
3435 start_encrypt = 1
35 start_decrypt = 2
3636 PPCODE:
3737 {
3838 STRLEN k_len=0;
7272 RETVAL = newSVpvn("", 0);
7373 }
7474 else {
75 RETVAL = NEWSV(0, in_data_len);
75 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
7676 SvPOK_only(RETVAL);
7777 SvCUR_set(RETVAL, in_data_len);
7878 out_data = (unsigned char *)SvPVX(RETVAL);
55 new(char * class, char * cipher_name, int padding=1, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct ecb_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->padding_mode = padding;
2627 Safefree(self);
2728
2829 void
29 _start(Crypt::Mode::ECB self, SV * key)
30 start_decrypt(Crypt::Mode::ECB self, SV * key)
3031 ALIAS:
3132 start_encrypt = 1
32 start_decrypt = 2
3333 PPCODE:
3434 {
3535 int rv;
9494
9595 if (in_data_len > 0) {
9696 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! */
9898 SvPOK_only(RETVAL);
9999 SvCUR_set(RETVAL, i);
100100 out_data = (unsigned char *)SvPVX(RETVAL);
175175 RETVAL = newSVpvn("", 0);
176176 }
177177 else {
178 RETVAL = NEWSV(0, i);
178 RETVAL = NEWSV(0, i); /* avoid zero! */
179179 SvPOK_only(RETVAL);
180180 SvCUR_set(RETVAL, i);
181181 out_data = (unsigned char *)SvPVX(RETVAL);
55 new(char * class, char * cipher_name, int rounds=0)
66 CODE:
77 {
8 LTC_UNUSED_PARAM(class);
89 Newz(0, RETVAL, 1, struct ofb_struct);
910 if (!RETVAL) croak("FATAL: Newz failed");
1011 RETVAL->direction = 0;
2425 Safefree(self);
2526
2627 void
27 _start(Crypt::Mode::OFB self, SV * key, SV * iv)
28 start_decrypt(Crypt::Mode::OFB self, SV * key, SV * iv)
2829 ALIAS:
2930 start_encrypt = 1
30 start_decrypt = 2
3131 PPCODE:
3232 {
3333 STRLEN k_len=0;
6767 RETVAL = newSVpvn("", 0);
6868 }
6969 else {
70 RETVAL = NEWSV(0, in_data_len);
70 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
7171 SvPOK_only(RETVAL);
7272 SvCUR_set(RETVAL, in_data_len);
7373 out_data = (unsigned char *)SvPVX(RETVAL);
44 CODE:
55 {
66 int rv;
7 LTC_UNUSED_PARAM(class);
78 Newz(0, RETVAL, 1, struct dh_struct);
89 if (!RETVAL) croak("FATAL: Newz failed");
910 RETVAL->key.type = -1;
207208 not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_groupsize(&self->key)), 0);
208209 /* type */
209210 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);
211212 RETVAL = newRV_noinc((SV*)rv_hash);
212213 OUTPUT:
213214 RETVAL
44 CODE:
55 {
66 int rv;
7 LTC_UNUSED_PARAM(class);
78 Newz(0, RETVAL, 1, struct dsa_struct);
89 if (!RETVAL) croak("FATAL: Newz failed");
910 RETVAL->key.type = -1;
228229 not_used = hv_store(rv_hash, "size", 4, newSViv(qsize), 0);
229230 /* type */
230231 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);
232233 RETVAL = newRV_noinc((SV*)rv_hash);
233234 OUTPUT:
234235 RETVAL
260261 RETVAL
261262
262263 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")
264265 CODE:
265266 {
266267 int rv, hash_id;
302303 RETVAL
303304
304305 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;
313315
314316 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 }
316325 rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
317326 &self->pstate, self->pindex,
318327 &self->key);
323332 RETVAL
324333
325334 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;
334344
335345 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
336346 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 }
338355 RETVAL = 1;
339356 stat = 0;
340357 rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
44 CODE:
55 {
66 int rv;
7 LTC_UNUSED_PARAM(class);
78 Newz(0, RETVAL, 1, struct ecc_struct);
89 if (!RETVAL) croak("FATAL: Newz failed");
910 RETVAL->pindex = find_prng("chacha20");
204205 not_used = hv_store(rv_hash, "size", 4, newSViv(esize), 0);
205206 /* type */
206207 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);
208209 RETVAL = newRV_noinc((SV*)rv_hash);
209210 OUTPUT:
210211 RETVAL
277278 RETVAL
278279
279280 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")
281282 CODE:
282283 {
283284 int rv, hash_id;
300301 RETVAL
301302
302303 SV *
303 _decrypt(Crypt::PK::ECC self, SV * data)
304 decrypt(Crypt::PK::ECC self, SV * data)
304305 CODE:
305306 {
306307 int rv;
319320 RETVAL
320321
321322 SV *
322 _sign(Crypt::PK::ECC self, SV * data)
323 sign_hash(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1")
323324 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;
332333
333334 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) {
336344 rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
337345 &self->pstate, self->pindex,
338346 &self->key);
349357 RETVAL
350358
351359 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")
353361 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;
362370
363371 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
364372 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 }
366381 RETVAL = 1;
367382 stat = 0;
368 if (ix == 1) {
383 if (ix == 2) {
369384 rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
370385 }
371386 else {
44 CODE:
55 {
66 int rv;
7 LTC_UNUSED_PARAM(class);
78 Newz(0, RETVAL, 1, struct rsa_struct);
89 if (!RETVAL) croak("FATAL: Newz failed");
910 RETVAL->key.type = -1;
260261 not_used = hv_store(rv_hash, "size", 4, newSViv(nsize), 0);
261262 /* type */
262263 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);
264265 RETVAL = newRV_noinc((SV*)rv_hash);
265266 OUTPUT:
266267 RETVAL
292293 RETVAL
293294
294295 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)
296297 CODE:
297298 {
298299 int rv, hash_id;
337338 RETVAL
338339
339340 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)
341342 CODE:
342343 {
343344 int rv, hash_id, stat;
382383 RETVAL
383384
384385 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
386389 CODE:
387390 {
388391 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;
393395
394396 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 }
397405 if (strnEQ(padding, "pss", 3)) {
398406 hash_id = _find_hash(hash_name);
399407 if (hash_id == -1) croak("FATAL: find_hash failed for '%s'", hash_name);
426434 RETVAL
427435
428436 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
430440 CODE:
431441 {
432442 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;
439446
440447 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
441448 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 }
443457 RETVAL = 1;
444458 stat = 0;
445459 if (strnEQ(padding, "pss", 3)) {
88 unsigned char *ent=NULL;
99 STRLEN ent_len=0;
1010 unsigned char entropy_buf[40];
11 char *default_name = "ChaCha20";
12 char *prng_name = default_name;
11 char *prng_name = (char *)"ChaCha20";
1312 SV *entropy = &PL_sv_undef;
1413
1514 /* we need to handle:
9493 }
9594
9695 SV *
97 bytes(Crypt::PRNG self, STRLEN output_len)
96 bytes(Crypt::PRNG self, unsigned long output_len)
9897 ALIAS:
9998 bytes_hex = 1
10099 bytes_b64 = 2
107106 unsigned char *rdata, *tmp;
108107 unsigned char entropy_buf[40];
109108
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);
154111 }
155112 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 }
165168 }
166169 }
167170 }
6565 int rv;
6666 unsigned char *out_data;
6767
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 }
7681 }
7782 }
7883 OUTPUT:
9196 RETVAL = newSVpvn("", 0);
9297 }
9398 else {
94 RETVAL = NEWSV(0, in_data_len);
99 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
95100 SvPOK_only(RETVAL);
96101 SvCUR_set(RETVAL, in_data_len);
97102 out_data = (unsigned char *)SvPVX(RETVAL);
4444 int rv;
4545 unsigned char *out_data;
4646
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 }
5560 }
5661 }
5762 OUTPUT:
7075 RETVAL = newSVpvn("", 0);
7176 }
7277 else {
73 RETVAL = NEWSV(0, in_data_len);
78 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
7479 SvPOK_only(RETVAL);
7580 SvCUR_set(RETVAL, in_data_len);
7681 out_data = (unsigned char *)SvPVX(RETVAL);
5555 int rv;
5656 unsigned char *out_data;
5757
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 }
6671 }
6772 }
6873 OUTPUT:
8186 RETVAL = newSVpvn("", 0);
8287 }
8388 else {
84 RETVAL = NEWSV(0, in_data_len);
89 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
8590 SvPOK_only(RETVAL);
8691 SvCUR_set(RETVAL, in_data_len);
8792 out_data = (unsigned char *)SvPVX(RETVAL);
5252 int rv;
5353 unsigned char *out_data;
5454
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 }
6368 }
6469 }
6570 OUTPUT:
7883 RETVAL = newSVpvn("", 0);
7984 }
8085 else {
81 RETVAL = NEWSV(0, in_data_len);
86 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
8287 SvPOK_only(RETVAL);
8388 SvCUR_set(RETVAL, in_data_len);
8489 out_data = (unsigned char *)SvPVX(RETVAL);
5252 int rv;
5353 unsigned char *out_data;
5454
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 }
6368 }
6469 }
6570 OUTPUT:
7883 RETVAL = newSVpvn("", 0);
7984 }
8085 else {
81 RETVAL = NEWSV(0, in_data_len);
86 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
8287 SvPOK_only(RETVAL);
8388 SvCUR_set(RETVAL, in_data_len);
8489 out_data = (unsigned char *)SvPVX(RETVAL);
5858 int rv;
5959 unsigned char *out_data;
6060
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 }
6974 }
7075 }
7176 OUTPUT:
8489 RETVAL = newSVpvn("", 0);
8590 }
8691 else {
87 RETVAL = NEWSV(0, in_data_len);
92 RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
8893 SvPOK_only(RETVAL);
8994 SvCUR_set(RETVAL, in_data_len);
9095 out_data = (unsigned char *)SvPVX(RETVAL);
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
5114
5215 1;
5316
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
4214
4315 1;
4416
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
5414
5515 # obsolete, only for backwards compatibility
5616 sub header_add { goto &adata_add }
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
4614
4715 1;
4816
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
4514
4615 # obsolete, only for backwards compatibility
4716 sub aad_add { goto &adata_add }
1111 use Carp;
1212 $Carp::Internal{(__PACKAGE__)}++;
1313 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 }
6514
6615 1;
6716
9494 croak "FATAL: invalid or unsupported DSA key format";
9595 }
9696
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
10897 ### FUNCTIONS
10998
11099 sub dsa_encrypt {
565565 croak "FATAL: invalid or unsupported EC key format";
566566 }
567567
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
617568 sub curve2hash {
618569 my $self = shift;
619570 my $kh = $self->key2hash;
624575 Gx => $kh->{curve_Gx},
625576 Gy => $kh->{curve_Gy},
626577 cofactor => $kh->{curve_cofactor},
627 order => $kh->{curve_order}
578 order => $kh->{curve_order},
579 oid => $kh->{curve_oid},
628580 };
629581 }
630582
162162 croak "FATAL: invalid or unsupported RSA key format";
163163 }
164164
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
181165 ### FUNCTIONS
182166
183167 sub rsa_encrypt {
00 use strict;
11 use warnings;
22
3 use Test::More tests => 12;
3 use Test::More tests => 13;
44
55 use Crypt::AuthEnc::CCM qw( ccm_encrypt_authenticate ccm_decrypt_verify );
66
4444 }
4545
4646 {
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");
4850 is(unpack('H*', $ct), "96b0114ff47da72e92631aadce84f203a8168b20", "ccm_encrypt_authenticate: ciphertext (no header)");
4951 is(unpack('H*', $tag), "9e9cba5dd4939d0d8e2687c85c5d3b89", "ccm_encrypt_authenticate: tag (no header)");
5052 my $pt = ccm_decrypt_verify('AES', $key, $nonce, "", $ct, $tag);