Codebase list libcryptx-perl / 0384d07
UNIX newlines Karel Miko 8 years ago
16 changed file(s) with 2156 addition(s) and 2156 deletion(s). Raw diff Collapse all Expand all
0 NAME
1 CryptX - Crypto toolkit (self-contained no external libraries needed)
2
3 DESCRIPTION
4 Cryptography in CryptX is based on
5 <https://github.com/libtom/libtomcrypt>
6
7 Currently available modules:
8
9 * Ciphers - see Crypt::Cipher and related modules
10
11 Crypt::Cipher::AES, Crypt::Cipher::Anubis, Crypt::Cipher::Blowfish,
12 Crypt::Cipher::Camellia, Crypt::Cipher::CAST5, Crypt::Cipher::DES,
13 Crypt::Cipher::DES_EDE, Crypt::Cipher::KASUMI,
14 Crypt::Cipher::Khazad, Crypt::Cipher::MULTI2,
15 Crypt::Cipher::Noekeon, Crypt::Cipher::RC2, Crypt::Cipher::RC5,
16 Crypt::Cipher::RC6, Crypt::Cipher::SAFERP,
17 Crypt::Cipher::SAFER_K128, Crypt::Cipher::SAFER_K64,
18 Crypt::Cipher::SAFER_SK128, Crypt::Cipher::SAFER_SK64,
19 Crypt::Cipher::SEED, Crypt::Cipher::Skipjack,
20 Crypt::Cipher::Twofish, Crypt::Cipher::XTEA
21
22 * Block cipher modes
23
24 Crypt::Mode::CBC, Crypt::Mode::CFB, Crypt::Mode::CTR,
25 Crypt::Mode::ECB, Crypt::Mode::OFB
26
27 * Authenticated encryption modes
28
29 Crypt::AuthEnc::CCM, Crypt::AuthEnc::EAX, Crypt::AuthEnc::GCM,
30 Crypt::AuthEnc::OCB
31
32 * Hash Functions - see Crypt::Digest and related modules
33
34 Crypt::Digest::CHAES, Crypt::Digest::MD2, Crypt::Digest::MD4,
35 Crypt::Digest::MD5, Crypt::Digest::RIPEMD128,
36 Crypt::Digest::RIPEMD160, Crypt::Digest::RIPEMD256,
37 Crypt::Digest::RIPEMD320, Crypt::Digest::SHA1,
38 Crypt::Digest::SHA224, Crypt::Digest::SHA256, Crypt::Digest::SHA384,
39 Crypt::Digest::SHA512, Crypt::Digest::SHA512_224,
40 Crypt::Digest::SHA512_256, Crypt::Digest::Tiger192,
41 Crypt::Digest::Whirlpool
42
43 * Message Authentication Codes
44
45 Crypt::Mac::F9, Crypt::Mac::HMAC, Crypt::Mac::OMAC,
46 Crypt::Mac::Pelican, Crypt::Mac::PMAC, Crypt::Mac::XCBC
47
48 * Public key cryptography
49
50 Crypt::PK::RSA, Crypt::PK::DSA, Crypt::PK::ECC, Crypt::PK::DH
51
52 * Cryptographically secure random number generators
53
54 Crypt::PRNG, Crypt::PRNG::Fortuna, Crypt::PRNG::Yarrow,
55 Crypt::PRNG::RC4, Crypt::PRNG::Sober128
56
57 * Key derivation functions - PBKDF1, PBKFD2 and HKDF
58
59 Crypt::KeyDerivation
60
61 LICENSE
62 This program is free software; you can redistribute it and/or modify it
63 under the same terms as Perl itself.
64
65 COPYRIGHT
66 Copyright (c) 2013-2015 DCIT, a.s. <http://www.dcit.cz> / Karel Miko
67
0 NAME
1 CryptX - Crypto toolkit (self-contained no external libraries needed)
2
3 DESCRIPTION
4 Cryptography in CryptX is based on
5 <https://github.com/libtom/libtomcrypt>
6
7 Currently available modules:
8
9 * Ciphers - see Crypt::Cipher and related modules
10
11 Crypt::Cipher::AES, Crypt::Cipher::Anubis, Crypt::Cipher::Blowfish,
12 Crypt::Cipher::Camellia, Crypt::Cipher::CAST5, Crypt::Cipher::DES,
13 Crypt::Cipher::DES_EDE, Crypt::Cipher::KASUMI,
14 Crypt::Cipher::Khazad, Crypt::Cipher::MULTI2,
15 Crypt::Cipher::Noekeon, Crypt::Cipher::RC2, Crypt::Cipher::RC5,
16 Crypt::Cipher::RC6, Crypt::Cipher::SAFERP,
17 Crypt::Cipher::SAFER_K128, Crypt::Cipher::SAFER_K64,
18 Crypt::Cipher::SAFER_SK128, Crypt::Cipher::SAFER_SK64,
19 Crypt::Cipher::SEED, Crypt::Cipher::Skipjack,
20 Crypt::Cipher::Twofish, Crypt::Cipher::XTEA
21
22 * Block cipher modes
23
24 Crypt::Mode::CBC, Crypt::Mode::CFB, Crypt::Mode::CTR,
25 Crypt::Mode::ECB, Crypt::Mode::OFB
26
27 * Authenticated encryption modes
28
29 Crypt::AuthEnc::CCM, Crypt::AuthEnc::EAX, Crypt::AuthEnc::GCM,
30 Crypt::AuthEnc::OCB
31
32 * Hash Functions - see Crypt::Digest and related modules
33
34 Crypt::Digest::CHAES, Crypt::Digest::MD2, Crypt::Digest::MD4,
35 Crypt::Digest::MD5, Crypt::Digest::RIPEMD128,
36 Crypt::Digest::RIPEMD160, Crypt::Digest::RIPEMD256,
37 Crypt::Digest::RIPEMD320, Crypt::Digest::SHA1,
38 Crypt::Digest::SHA224, Crypt::Digest::SHA256, Crypt::Digest::SHA384,
39 Crypt::Digest::SHA512, Crypt::Digest::SHA512_224,
40 Crypt::Digest::SHA512_256, Crypt::Digest::Tiger192,
41 Crypt::Digest::Whirlpool
42
43 * Message Authentication Codes
44
45 Crypt::Mac::F9, Crypt::Mac::HMAC, Crypt::Mac::OMAC,
46 Crypt::Mac::Pelican, Crypt::Mac::PMAC, Crypt::Mac::XCBC
47
48 * Public key cryptography
49
50 Crypt::PK::RSA, Crypt::PK::DSA, Crypt::PK::ECC, Crypt::PK::DH
51
52 * Cryptographically secure random number generators
53
54 Crypt::PRNG, Crypt::PRNG::Fortuna, Crypt::PRNG::Yarrow,
55 Crypt::PRNG::RC4, Crypt::PRNG::Sober128
56
57 * Key derivation functions - PBKDF1, PBKFD2 and HKDF
58
59 Crypt::KeyDerivation
60
61 LICENSE
62 This program is free software; you can redistribute it and/or modify it
63 under the same terms as Perl itself.
64
65 COPYRIGHT
66 Copyright (c) 2013-2015 DCIT, a.s. <http://www.dcit.cz> / Karel Miko
67
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::CCM
1
2 void
3 _memory_encrypt(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext)
4 PPCODE:
5 {
6 STRLEN k_len, n_len, h_len, pt_len;
7 unsigned char *k, *n, *h, *pt;
8 int rv, id;
9 unsigned char tag[MAXBLOCKSIZE];
10 SV *ct;
11
12 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
13 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
14 if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
15 if (!SvPOK(plaintext)) croak("FATAL: plaintext must be string/buffer scalar");
16 k = (unsigned char *) SvPVbyte(key, k_len);
17 n = (unsigned char *) SvPVbyte(nonce, n_len);
18 h = (unsigned char *) SvPVbyte(header, h_len);
19 pt = (unsigned char *) SvPVbyte(plaintext, pt_len);
20
21 id = find_cipher(cipher_name);
22 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
23
24 ct = NEWSV(0, pt_len);
25 SvPOK_only(ct);
26 SvCUR_set(ct, pt_len);
27
28 if(tag_len<4 || tag_len>16) tag_len = 16;
29
30 rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len,
31 pt, (unsigned long)pt_len, (unsigned char *)SvPV_nolen(ct), tag, &tag_len, CCM_ENCRYPT);
32 if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv));
33
34 XPUSHs(sv_2mortal(ct));
35 XPUSHs(sv_2mortal(newSVpvn((char*)tag,tag_len)));
36
37 /* int ccm_memory( int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction); */
46
47 }
48
49 void
50 _memory_decrypt(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tag)
51 PPCODE:
52 {
53 STRLEN k_len, n_len, h_len, ct_len, t_len;
54 unsigned char *k, *n, *h, *ct, *t;
55 int rv, id;
56 unsigned char xtag[MAXBLOCKSIZE];
57 unsigned long xtag_len;
58 SV *pt;
59
60 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
61 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
62 if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
63 if (!SvPOK(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar");
64 if (!SvPOK(tag)) croak("FATAL: tag must be string/buffer scalar");
65 k = (unsigned char *) SvPVbyte(key, k_len);
66 n = (unsigned char *) SvPVbyte(nonce, n_len);
67 h = (unsigned char *) SvPVbyte(header, h_len);
68 ct = (unsigned char *) SvPVbyte(ciphertext, ct_len);
69 t = (unsigned char *) SvPVbyte(tag, t_len);
70
71 id = find_cipher(cipher_name);
72 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
73
74 pt = NEWSV(0, ct_len);
75 SvPOK_only(pt);
76 SvCUR_set(pt, ct_len);
77
78 xtag_len = (unsigned long)t_len;
79
80 rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len,
81 (unsigned char *)SvPV_nolen(pt), (unsigned long)ct_len, ct, xtag, &xtag_len, CCM_DECRYPT);
82 if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv));
83
84 if (t_len!=xtag_len) {
85 XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */
86 }
87 else if (memNE(t, xtag, xtag_len)) {
88 XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */
89 }
90 else {
91 XPUSHs(sv_2mortal(pt));
92 }
93 }
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::CCM
1
2 void
3 _memory_encrypt(char *cipher_name, SV *key, SV *nonce, SV *header, unsigned long tag_len, SV *plaintext)
4 PPCODE:
5 {
6 STRLEN k_len, n_len, h_len, pt_len;
7 unsigned char *k, *n, *h, *pt;
8 int rv, id;
9 unsigned char tag[MAXBLOCKSIZE];
10 SV *ct;
11
12 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
13 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
14 if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
15 if (!SvPOK(plaintext)) croak("FATAL: plaintext must be string/buffer scalar");
16 k = (unsigned char *) SvPVbyte(key, k_len);
17 n = (unsigned char *) SvPVbyte(nonce, n_len);
18 h = (unsigned char *) SvPVbyte(header, h_len);
19 pt = (unsigned char *) SvPVbyte(plaintext, pt_len);
20
21 id = find_cipher(cipher_name);
22 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
23
24 ct = NEWSV(0, pt_len);
25 SvPOK_only(ct);
26 SvCUR_set(ct, pt_len);
27
28 if(tag_len<4 || tag_len>16) tag_len = 16;
29
30 rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len,
31 pt, (unsigned long)pt_len, (unsigned char *)SvPV_nolen(ct), tag, &tag_len, CCM_ENCRYPT);
32 if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv));
33
34 XPUSHs(sv_2mortal(ct));
35 XPUSHs(sv_2mortal(newSVpvn((char*)tag,tag_len)));
36
37 /* int ccm_memory( int cipher,
38 const unsigned char *key, unsigned long keylen,
39 symmetric_key *uskey,
40 const unsigned char *nonce, unsigned long noncelen,
41 const unsigned char *header, unsigned long headerlen,
42 unsigned char *pt, unsigned long ptlen,
43 unsigned char *ct,
44 unsigned char *tag, unsigned long *taglen,
45 int direction); */
46
47 }
48
49 void
50 _memory_decrypt(char *cipher_name, SV *key, SV *nonce, SV *header, SV *ciphertext, SV *tag)
51 PPCODE:
52 {
53 STRLEN k_len, n_len, h_len, ct_len, t_len;
54 unsigned char *k, *n, *h, *ct, *t;
55 int rv, id;
56 unsigned char xtag[MAXBLOCKSIZE];
57 unsigned long xtag_len;
58 SV *pt;
59
60 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
61 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
62 if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
63 if (!SvPOK(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar");
64 if (!SvPOK(tag)) croak("FATAL: tag must be string/buffer scalar");
65 k = (unsigned char *) SvPVbyte(key, k_len);
66 n = (unsigned char *) SvPVbyte(nonce, n_len);
67 h = (unsigned char *) SvPVbyte(header, h_len);
68 ct = (unsigned char *) SvPVbyte(ciphertext, ct_len);
69 t = (unsigned char *) SvPVbyte(tag, t_len);
70
71 id = find_cipher(cipher_name);
72 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
73
74 pt = NEWSV(0, ct_len);
75 SvPOK_only(pt);
76 SvCUR_set(pt, ct_len);
77
78 xtag_len = (unsigned long)t_len;
79
80 rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len,
81 (unsigned char *)SvPV_nolen(pt), (unsigned long)ct_len, ct, xtag, &xtag_len, CCM_DECRYPT);
82 if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv));
83
84 if (t_len!=xtag_len) {
85 XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */
86 }
87 else if (memNE(t, xtag, xtag_len)) {
88 XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */
89 }
90 else {
91 XPUSHs(sv_2mortal(pt));
92 }
93 }
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::EAX
1
2 Crypt::AuthEnc::EAX
3 _new(char * cipher_name, SV * key, SV * nonce, SV * header=&PL_sv_undef)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 unsigned char *n=NULL;
9 STRLEN n_len=0;
10 unsigned char *h=NULL;
11 STRLEN h_len=0;
12 int id;
13
14 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
15 k = (unsigned char *) SvPVbyte(key, k_len);
16 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
17 n = (unsigned char *) SvPVbyte(nonce, n_len);
18 if(SvOK(header)) { /* header is optional param */
19 if(!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
20 h = (unsigned char *) SvPVbyte(header, h_len);
21 }
22
23 id = find_cipher(cipher_name);
24 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
25
26 Newz(0, RETVAL, 1, struct eax_struct);
27 if (!RETVAL) croak("FATAL: Newz failed");
28
29 if (eax_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len) != CRYPT_OK) {
30 croak("FATAL: eax setup failed");
31 }
32 }
33 OUTPUT:
34 RETVAL
35
36 void
37 DESTROY(Crypt::AuthEnc::EAX self)
38 CODE:
39 Safefree(self);
40
41 Crypt::AuthEnc::EAX
42 clone(Crypt::AuthEnc::EAX self)
43 CODE:
44 Newz(0, RETVAL, 1, struct eax_struct);
45 if (!RETVAL) croak("FATAL: Newz failed");
46 Copy(&self->state, &RETVAL->state, 1, struct eax_struct);
47 OUTPUT:
48 RETVAL
49
50 SV *
51 encrypt_add(Crypt::AuthEnc::EAX self, SV * data)
52 CODE:
53 {
54 int rv;
55 STRLEN in_data_len;
56 unsigned char *in_data, *out_data;
57
58 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
59 if (in_data_len==0) {
60 RETVAL = newSVpvn("", 0);
61 }
62 else {
63 RETVAL = NEWSV(0, in_data_len);
64 SvPOK_only(RETVAL);
65 SvCUR_set(RETVAL, in_data_len);
66 out_data = (unsigned char *)SvPV_nolen(RETVAL);
67 rv = eax_encrypt(&self->state, in_data, out_data, (unsigned long)in_data_len);
68 if (rv != CRYPT_OK) croak("FATAL: eax_encrypt failed: %s", error_to_string(rv));
69 }
70 }
71 OUTPUT:
72 RETVAL
73
74 SV *
75 decrypt_add(Crypt::AuthEnc::EAX self, SV * data)
76 CODE:
77 {
78 int rv;
79 STRLEN in_data_len;
80 unsigned char *in_data, *out_data;
81
82 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
83 if (in_data_len==0) {
84 RETVAL = newSVpvn("", 0);
85 }
86 else {
87 RETVAL = NEWSV(0, in_data_len);
88 SvPOK_only(RETVAL);
89 SvCUR_set(RETVAL, in_data_len);
90 out_data = (unsigned char *)SvPV_nolen(RETVAL);
91 rv = eax_decrypt(&self->state, in_data, out_data, (unsigned long)in_data_len);
92 if (rv != CRYPT_OK) croak("FATAL: eax_decrypt failed: %s", error_to_string(rv));
93 }
94 }
95 OUTPUT:
96 RETVAL
97
98 void
99 encrypt_done(Crypt::AuthEnc::EAX self)
100 PPCODE:
101 {
102 int rv;
103 unsigned char tag[MAXBLOCKSIZE];
104 unsigned long tag_len = sizeof(tag);
105
106 rv = eax_done(&self->state, tag, &tag_len);
107 if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
108 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
109 }
110
111 void
112 decrypt_done(Crypt::AuthEnc::EAX self, ...)
113 PPCODE:
114 {
115 int rv;
116 unsigned char tag[MAXBLOCKSIZE];
117 unsigned long tag_len = sizeof(tag);
118 STRLEN expected_tag_len;
119 unsigned char *expected_tag;
120
121 rv = eax_done(&self->state, tag, &tag_len);
122 if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
123 if (items == 1) {
124 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
125 }
126 else {
127 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
128 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
129 if (expected_tag_len!=tag_len) {
130 XPUSHs(sv_2mortal(newSViv(0))); /* false */
131 }
132 else if (memNE(expected_tag, tag, tag_len)) {
133 XPUSHs(sv_2mortal(newSViv(0))); /* false */
134 }
135 else {
136 XPUSHs(sv_2mortal(newSViv(1))); /* true */
137 }
138 }
139 }
140
141 int
142 header_add(Crypt::AuthEnc::EAX self, SV * header)
143 CODE:
144 {
145 STRLEN h_len;
146 unsigned char *h;
147 h = (unsigned char *)SvPVbyte(header, h_len);
148 RETVAL = eax_addheader(&self->state, h, (unsigned long)h_len);
149 }
150 OUTPUT:
151 RETVAL
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::EAX
1
2 Crypt::AuthEnc::EAX
3 _new(char * cipher_name, SV * key, SV * nonce, SV * header=&PL_sv_undef)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 unsigned char *n=NULL;
9 STRLEN n_len=0;
10 unsigned char *h=NULL;
11 STRLEN h_len=0;
12 int id;
13
14 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
15 k = (unsigned char *) SvPVbyte(key, k_len);
16 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
17 n = (unsigned char *) SvPVbyte(nonce, n_len);
18 if(SvOK(header)) { /* header is optional param */
19 if(!SvPOK(header)) croak("FATAL: header must be string/buffer scalar");
20 h = (unsigned char *) SvPVbyte(header, h_len);
21 }
22
23 id = find_cipher(cipher_name);
24 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
25
26 Newz(0, RETVAL, 1, struct eax_struct);
27 if (!RETVAL) croak("FATAL: Newz failed");
28
29 if (eax_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len, h, (unsigned long)h_len) != CRYPT_OK) {
30 croak("FATAL: eax setup failed");
31 }
32 }
33 OUTPUT:
34 RETVAL
35
36 void
37 DESTROY(Crypt::AuthEnc::EAX self)
38 CODE:
39 Safefree(self);
40
41 Crypt::AuthEnc::EAX
42 clone(Crypt::AuthEnc::EAX self)
43 CODE:
44 Newz(0, RETVAL, 1, struct eax_struct);
45 if (!RETVAL) croak("FATAL: Newz failed");
46 Copy(&self->state, &RETVAL->state, 1, struct eax_struct);
47 OUTPUT:
48 RETVAL
49
50 SV *
51 encrypt_add(Crypt::AuthEnc::EAX self, SV * data)
52 CODE:
53 {
54 int rv;
55 STRLEN in_data_len;
56 unsigned char *in_data, *out_data;
57
58 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
59 if (in_data_len==0) {
60 RETVAL = newSVpvn("", 0);
61 }
62 else {
63 RETVAL = NEWSV(0, in_data_len);
64 SvPOK_only(RETVAL);
65 SvCUR_set(RETVAL, in_data_len);
66 out_data = (unsigned char *)SvPV_nolen(RETVAL);
67 rv = eax_encrypt(&self->state, in_data, out_data, (unsigned long)in_data_len);
68 if (rv != CRYPT_OK) croak("FATAL: eax_encrypt failed: %s", error_to_string(rv));
69 }
70 }
71 OUTPUT:
72 RETVAL
73
74 SV *
75 decrypt_add(Crypt::AuthEnc::EAX self, SV * data)
76 CODE:
77 {
78 int rv;
79 STRLEN in_data_len;
80 unsigned char *in_data, *out_data;
81
82 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
83 if (in_data_len==0) {
84 RETVAL = newSVpvn("", 0);
85 }
86 else {
87 RETVAL = NEWSV(0, in_data_len);
88 SvPOK_only(RETVAL);
89 SvCUR_set(RETVAL, in_data_len);
90 out_data = (unsigned char *)SvPV_nolen(RETVAL);
91 rv = eax_decrypt(&self->state, in_data, out_data, (unsigned long)in_data_len);
92 if (rv != CRYPT_OK) croak("FATAL: eax_decrypt failed: %s", error_to_string(rv));
93 }
94 }
95 OUTPUT:
96 RETVAL
97
98 void
99 encrypt_done(Crypt::AuthEnc::EAX self)
100 PPCODE:
101 {
102 int rv;
103 unsigned char tag[MAXBLOCKSIZE];
104 unsigned long tag_len = sizeof(tag);
105
106 rv = eax_done(&self->state, tag, &tag_len);
107 if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
108 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
109 }
110
111 void
112 decrypt_done(Crypt::AuthEnc::EAX self, ...)
113 PPCODE:
114 {
115 int rv;
116 unsigned char tag[MAXBLOCKSIZE];
117 unsigned long tag_len = sizeof(tag);
118 STRLEN expected_tag_len;
119 unsigned char *expected_tag;
120
121 rv = eax_done(&self->state, tag, &tag_len);
122 if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv));
123 if (items == 1) {
124 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
125 }
126 else {
127 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
128 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
129 if (expected_tag_len!=tag_len) {
130 XPUSHs(sv_2mortal(newSViv(0))); /* false */
131 }
132 else if (memNE(expected_tag, tag, tag_len)) {
133 XPUSHs(sv_2mortal(newSViv(0))); /* false */
134 }
135 else {
136 XPUSHs(sv_2mortal(newSViv(1))); /* true */
137 }
138 }
139 }
140
141 int
142 header_add(Crypt::AuthEnc::EAX self, SV * header)
143 CODE:
144 {
145 STRLEN h_len;
146 unsigned char *h;
147 h = (unsigned char *)SvPVbyte(header, h_len);
148 RETVAL = eax_addheader(&self->state, h, (unsigned long)h_len);
149 }
150 OUTPUT:
151 RETVAL
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::GCM
1
2 Crypt::AuthEnc::GCM
3 _new(char * cipher_name, SV * key)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 int id;
9
10 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
11 k = (unsigned char *) SvPVbyte(key, k_len);
12
13
14 id = find_cipher(cipher_name);
15 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
16
17 Newz(0, RETVAL, 1, struct gcm_struct);
18 if (!RETVAL) croak("FATAL: Newz failed");
19
20 if (gcm_init(&RETVAL->state, id, k, (unsigned long)k_len) != CRYPT_OK) {
21 croak("FATAL: gcm setup failed");
22 }
23 }
24 OUTPUT:
25 RETVAL
26
27 void
28 DESTROY(Crypt::AuthEnc::GCM self)
29 CODE:
30 Safefree(self);
31
32 Crypt::AuthEnc::GCM
33 clone(Crypt::AuthEnc::GCM self)
34 CODE:
35 Newz(0, RETVAL, 1, struct gcm_struct);
36 if (!RETVAL) croak("FATAL: Newz failed");
37 Copy(&self->state, &RETVAL->state, 1, struct gcm_struct);
38 OUTPUT:
39 RETVAL
40
41 int
42 reset(Crypt::AuthEnc::GCM self)
43 CODE:
44 {
45 int rv;
46 rv = gcm_reset(&self->state);
47 if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv));
48 RETVAL = rv;
49 }
50 OUTPUT:
51 RETVAL
52
53 SV *
54 encrypt_add(Crypt::AuthEnc::GCM self, SV * data)
55 CODE:
56 {
57 int rv;
58 STRLEN in_data_len;
59 unsigned char *in_data, *out_data;
60
61 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
62 if (in_data_len==0) {
63 RETVAL = newSVpvn("", 0);
64 }
65 else
66 {
67 RETVAL = NEWSV(0, in_data_len);
68 SvPOK_only(RETVAL);
69 SvCUR_set(RETVAL, in_data_len);
70 out_data = (unsigned char *)SvPV_nolen(RETVAL);
71 rv = gcm_process(&self->state, in_data, (unsigned long)in_data_len, out_data, GCM_ENCRYPT);
72 if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv));
73 }
74 }
75 OUTPUT:
76 RETVAL
77
78 int
79 iv_add(Crypt::AuthEnc::GCM self, SV * data)
80 CODE:
81 {
82 int rv;
83 STRLEN in_data_len;
84 unsigned char *in_data;
85
86 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
87 rv = gcm_add_iv(&self->state, in_data, (unsigned long)in_data_len);
88 if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv));
89 RETVAL = rv;
90 }
91 OUTPUT:
92 RETVAL
93
94 int
95 adata_add(Crypt::AuthEnc::GCM self, SV * data)
96 CODE:
97 {
98 int rv;
99 STRLEN in_data_len;
100 unsigned char *in_data;
101
102 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
103 rv = gcm_add_aad(&self->state, in_data, (unsigned long)in_data_len);
104 if (rv != CRYPT_OK) croak("FATAL: gcm_add_aad failed: %s", error_to_string(rv));
105 RETVAL = rv;
106 }
107 OUTPUT:
108 RETVAL
109
110 SV *
111 decrypt_add(Crypt::AuthEnc::GCM self, SV * data)
112 CODE:
113 {
114 int rv;
115 STRLEN in_data_len;
116 unsigned char *in_data, *out_data;
117
118 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
119 if (in_data_len==0) {
120 RETVAL = newSVpvn("", 0);
121 }
122 else {
123 RETVAL = NEWSV(0, in_data_len);
124 SvPOK_only(RETVAL);
125 SvCUR_set(RETVAL, in_data_len);
126 out_data = (unsigned char *)SvPV_nolen(RETVAL);
127 rv = gcm_process(&self->state, out_data, (unsigned long)in_data_len, in_data, GCM_DECRYPT);
128 if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv));
129 }
130 }
131 OUTPUT:
132 RETVAL
133
134
135 void
136 encrypt_done(Crypt::AuthEnc::GCM self)
137 PPCODE:
138 {
139 int rv;
140 unsigned char tag[MAXBLOCKSIZE];
141 unsigned long tag_len = sizeof(tag);
142
143 rv = gcm_done(&self->state, tag, &tag_len);
144 if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv));
145 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
146 }
147
148 void
149 decrypt_done(Crypt::AuthEnc::GCM self, ...)
150 PPCODE:
151 {
152 int rv;
153 unsigned char tag[MAXBLOCKSIZE];
154 unsigned long tag_len = sizeof(tag);
155 STRLEN expected_tag_len;
156 unsigned char *expected_tag;
157
158 rv = gcm_done(&self->state, tag, &tag_len);
159 if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv));
160 if (items == 1) {
161 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
162 }
163 else {
164 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
165 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
166 if (expected_tag_len!=tag_len) {
167 XPUSHs(sv_2mortal(newSViv(0))); /* false */
168 }
169 else if (memNE(expected_tag, tag, tag_len)) {
170 XPUSHs(sv_2mortal(newSViv(0))); /* false */
171 }
172 else {
173 XPUSHs(sv_2mortal(newSViv(1))); /* true */
174 }
175 }
176 }
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::GCM
1
2 Crypt::AuthEnc::GCM
3 _new(char * cipher_name, SV * key)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 int id;
9
10 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
11 k = (unsigned char *) SvPVbyte(key, k_len);
12
13
14 id = find_cipher(cipher_name);
15 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
16
17 Newz(0, RETVAL, 1, struct gcm_struct);
18 if (!RETVAL) croak("FATAL: Newz failed");
19
20 if (gcm_init(&RETVAL->state, id, k, (unsigned long)k_len) != CRYPT_OK) {
21 croak("FATAL: gcm setup failed");
22 }
23 }
24 OUTPUT:
25 RETVAL
26
27 void
28 DESTROY(Crypt::AuthEnc::GCM self)
29 CODE:
30 Safefree(self);
31
32 Crypt::AuthEnc::GCM
33 clone(Crypt::AuthEnc::GCM self)
34 CODE:
35 Newz(0, RETVAL, 1, struct gcm_struct);
36 if (!RETVAL) croak("FATAL: Newz failed");
37 Copy(&self->state, &RETVAL->state, 1, struct gcm_struct);
38 OUTPUT:
39 RETVAL
40
41 int
42 reset(Crypt::AuthEnc::GCM self)
43 CODE:
44 {
45 int rv;
46 rv = gcm_reset(&self->state);
47 if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv));
48 RETVAL = rv;
49 }
50 OUTPUT:
51 RETVAL
52
53 SV *
54 encrypt_add(Crypt::AuthEnc::GCM self, SV * data)
55 CODE:
56 {
57 int rv;
58 STRLEN in_data_len;
59 unsigned char *in_data, *out_data;
60
61 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
62 if (in_data_len==0) {
63 RETVAL = newSVpvn("", 0);
64 }
65 else
66 {
67 RETVAL = NEWSV(0, in_data_len);
68 SvPOK_only(RETVAL);
69 SvCUR_set(RETVAL, in_data_len);
70 out_data = (unsigned char *)SvPV_nolen(RETVAL);
71 rv = gcm_process(&self->state, in_data, (unsigned long)in_data_len, out_data, GCM_ENCRYPT);
72 if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv));
73 }
74 }
75 OUTPUT:
76 RETVAL
77
78 int
79 iv_add(Crypt::AuthEnc::GCM self, SV * data)
80 CODE:
81 {
82 int rv;
83 STRLEN in_data_len;
84 unsigned char *in_data;
85
86 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
87 rv = gcm_add_iv(&self->state, in_data, (unsigned long)in_data_len);
88 if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv));
89 RETVAL = rv;
90 }
91 OUTPUT:
92 RETVAL
93
94 int
95 adata_add(Crypt::AuthEnc::GCM self, SV * data)
96 CODE:
97 {
98 int rv;
99 STRLEN in_data_len;
100 unsigned char *in_data;
101
102 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
103 rv = gcm_add_aad(&self->state, in_data, (unsigned long)in_data_len);
104 if (rv != CRYPT_OK) croak("FATAL: gcm_add_aad failed: %s", error_to_string(rv));
105 RETVAL = rv;
106 }
107 OUTPUT:
108 RETVAL
109
110 SV *
111 decrypt_add(Crypt::AuthEnc::GCM self, SV * data)
112 CODE:
113 {
114 int rv;
115 STRLEN in_data_len;
116 unsigned char *in_data, *out_data;
117
118 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
119 if (in_data_len==0) {
120 RETVAL = newSVpvn("", 0);
121 }
122 else {
123 RETVAL = NEWSV(0, in_data_len);
124 SvPOK_only(RETVAL);
125 SvCUR_set(RETVAL, in_data_len);
126 out_data = (unsigned char *)SvPV_nolen(RETVAL);
127 rv = gcm_process(&self->state, out_data, (unsigned long)in_data_len, in_data, GCM_DECRYPT);
128 if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv));
129 }
130 }
131 OUTPUT:
132 RETVAL
133
134
135 void
136 encrypt_done(Crypt::AuthEnc::GCM self)
137 PPCODE:
138 {
139 int rv;
140 unsigned char tag[MAXBLOCKSIZE];
141 unsigned long tag_len = sizeof(tag);
142
143 rv = gcm_done(&self->state, tag, &tag_len);
144 if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv));
145 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
146 }
147
148 void
149 decrypt_done(Crypt::AuthEnc::GCM self, ...)
150 PPCODE:
151 {
152 int rv;
153 unsigned char tag[MAXBLOCKSIZE];
154 unsigned long tag_len = sizeof(tag);
155 STRLEN expected_tag_len;
156 unsigned char *expected_tag;
157
158 rv = gcm_done(&self->state, tag, &tag_len);
159 if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv));
160 if (items == 1) {
161 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
162 }
163 else {
164 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
165 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
166 if (expected_tag_len!=tag_len) {
167 XPUSHs(sv_2mortal(newSViv(0))); /* false */
168 }
169 else if (memNE(expected_tag, tag, tag_len)) {
170 XPUSHs(sv_2mortal(newSViv(0))); /* false */
171 }
172 else {
173 XPUSHs(sv_2mortal(newSViv(1))); /* true */
174 }
175 }
176 }
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::OCB
1
2 Crypt::AuthEnc::OCB
3 _new(char * cipher_name, SV * key, SV * nonce)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 unsigned char *n=NULL;
9 STRLEN n_len=0;
10 int id;
11
12 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
13 k = (unsigned char *) SvPVbyte(key, k_len);
14 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
15 n = (unsigned char *) SvPVbyte(nonce, n_len);
16
17 id = find_cipher(cipher_name);
18 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
19
20 Newz(0, RETVAL, 1, struct ocb_struct);
21 if (!RETVAL) croak("FATAL: Newz failed");
22
23 if (ocb3_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len) != CRYPT_OK) {
24 croak("FATAL: ocb setup failed");
25 }
26 }
27 OUTPUT:
28 RETVAL
29
30 void
31 DESTROY(Crypt::AuthEnc::OCB self)
32 CODE:
33 Safefree(self);
34
35 Crypt::AuthEnc::OCB
36 clone(Crypt::AuthEnc::OCB self)
37 CODE:
38 Newz(0, RETVAL, 1, struct ocb_struct);
39 if (!RETVAL) croak("FATAL: Newz failed");
40 Copy(&self->state, &RETVAL->state, 1, struct ocb_struct);
41 OUTPUT:
42 RETVAL
43
44 void
45 adata_add(Crypt::AuthEnc::OCB self, SV * data)
46 CODE:
47 {
48 int rv;
49 STRLEN in_data_len;
50 unsigned char *in_data;
51
52 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
53
54 if (in_data_len>0) {
55 rv = ocb3_add_aad(&self->state, in_data, (unsigned long)in_data_len);
56 if (rv != CRYPT_OK) croak("FATAL: ocb3_add_aad failed: %s", error_to_string(rv));
57 }
58 }
59
60 SV *
61 encrypt_add(Crypt::AuthEnc::OCB self, SV * data)
62 CODE:
63 {
64 int rv;
65 STRLEN in_data_len;
66 unsigned char *in_data, *out_data;
67
68 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
69 if (in_data_len==0) {
70 RETVAL = newSVpvn("", 0);
71 }
72 else {
73 RETVAL = NEWSV(0, in_data_len);
74 SvPOK_only(RETVAL);
75 SvCUR_set(RETVAL, in_data_len);
76 out_data = (unsigned char *)SvPV_nolen(RETVAL);
77
78 if (in_data_len % (&self->state)->block_len)
79 croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len);
80
81 rv = ocb3_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
82 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt failed: %s", error_to_string(rv));
83 }
84 }
85 OUTPUT:
86 RETVAL
87
88 SV *
89 encrypt_last(Crypt::AuthEnc::OCB self, SV * data)
90 CODE:
91 {
92 int rv;
93 STRLEN in_data_len;
94 unsigned char *in_data, *out_data;
95
96 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
97 if (in_data_len>0) {
98 RETVAL = NEWSV(0, in_data_len);
99 SvPOK_only(RETVAL);
100 SvCUR_set(RETVAL, in_data_len);
101 out_data = (unsigned char *)SvPV_nolen(RETVAL);
102 }
103 else {
104 RETVAL = newSVpvn("", 0);
105 out_data = NULL;
106 }
107 rv = ocb3_encrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data);
108 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv));
109 }
110 OUTPUT:
111 RETVAL
112
113 SV *
114 decrypt_add(Crypt::AuthEnc::OCB self, SV * data)
115 CODE:
116 {
117 int rv;
118 STRLEN in_data_len;
119 unsigned char *in_data, *out_data;
120
121 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
122 if (in_data_len==0) {
123 RETVAL = newSVpvn("", 0);
124 }
125 else {
126 RETVAL = NEWSV(0, in_data_len);
127 SvPOK_only(RETVAL);
128 SvCUR_set(RETVAL, in_data_len);
129 out_data = (unsigned char *)SvPV_nolen(RETVAL);
130
131 if (in_data_len % (&self->state)->block_len)
132 croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len);
133
134 rv = ocb3_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
135 if (rv != CRYPT_OK) croak("FATAL: ocb3_decrypt failed: %s", error_to_string(rv));
136 }
137 }
138 OUTPUT:
139 RETVAL
140
141 SV *
142 decrypt_last(Crypt::AuthEnc::OCB self, SV * data)
143 CODE:
144 {
145 int rv;
146 STRLEN in_data_len;
147 unsigned char *in_data, *out_data;
148
149 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
150 if (in_data_len>0) {
151 RETVAL = NEWSV(0, in_data_len);
152 SvPOK_only(RETVAL);
153 SvCUR_set(RETVAL, in_data_len);
154 out_data = (unsigned char *)SvPV_nolen(RETVAL);
155 }
156 else {
157 RETVAL = newSVpvn("", 0);
158 out_data = NULL;
159 }
160 rv = ocb3_decrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data);
161 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv));
162 }
163 OUTPUT:
164 RETVAL
165
166 void
167 encrypt_done(Crypt::AuthEnc::OCB self)
168 PPCODE:
169 {
170 int rv;
171 unsigned char tag[MAXBLOCKSIZE];
172 unsigned long tag_len = sizeof(tag);
173
174 rv = ocb3_done(&self->state, tag, &tag_len);
175 if (rv != CRYPT_OK) croak("FATAL: ocb3_done_encrypt failed: %s", error_to_string(rv));
176
177 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
178 }
179
180 void
181 decrypt_done(Crypt::AuthEnc::OCB self, ...)
182 PPCODE:
183 {
184 int rv;
185 unsigned char tag[MAXBLOCKSIZE];
186 unsigned long tag_len = sizeof(tag);
187 STRLEN expected_tag_len;
188 unsigned char *expected_tag;
189
190 rv = ocb3_done(&self->state, tag, &tag_len);
191 if (rv != CRYPT_OK) croak("FATAL: ocb3_done_decrypt failed: %s", error_to_string(rv));
192 if (items == 1) {
193 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
194 }
195 else {
196 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
197 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
198 if (expected_tag_len!=tag_len) {
199 XPUSHs(sv_2mortal(newSViv(0))); /* false */
200 }
201 else if (memNE(expected_tag, tag, tag_len)) {
202 XPUSHs(sv_2mortal(newSViv(0))); /* false */
203 }
204 else {
205 XPUSHs(sv_2mortal(newSViv(1))); /* true */
206 }
207 }
208 }
209
210 int
211 blocksize(Crypt::AuthEnc::OCB self)
212 CODE:
213 {
214 RETVAL = (&self->state)->block_len;
215 }
216 OUTPUT:
217 RETVAL
0 MODULE = CryptX PACKAGE = Crypt::AuthEnc::OCB
1
2 Crypt::AuthEnc::OCB
3 _new(char * cipher_name, SV * key, SV * nonce)
4 CODE:
5 {
6 STRLEN k_len=0;
7 unsigned char *k=NULL;
8 unsigned char *n=NULL;
9 STRLEN n_len=0;
10 int id;
11
12 if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar");
13 k = (unsigned char *) SvPVbyte(key, k_len);
14 if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar");
15 n = (unsigned char *) SvPVbyte(nonce, n_len);
16
17 id = find_cipher(cipher_name);
18 if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name);
19
20 Newz(0, RETVAL, 1, struct ocb_struct);
21 if (!RETVAL) croak("FATAL: Newz failed");
22
23 if (ocb3_init(&RETVAL->state, id, k, (unsigned long)k_len, n, (unsigned long)n_len) != CRYPT_OK) {
24 croak("FATAL: ocb setup failed");
25 }
26 }
27 OUTPUT:
28 RETVAL
29
30 void
31 DESTROY(Crypt::AuthEnc::OCB self)
32 CODE:
33 Safefree(self);
34
35 Crypt::AuthEnc::OCB
36 clone(Crypt::AuthEnc::OCB self)
37 CODE:
38 Newz(0, RETVAL, 1, struct ocb_struct);
39 if (!RETVAL) croak("FATAL: Newz failed");
40 Copy(&self->state, &RETVAL->state, 1, struct ocb_struct);
41 OUTPUT:
42 RETVAL
43
44 void
45 adata_add(Crypt::AuthEnc::OCB self, SV * data)
46 CODE:
47 {
48 int rv;
49 STRLEN in_data_len;
50 unsigned char *in_data;
51
52 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
53
54 if (in_data_len>0) {
55 rv = ocb3_add_aad(&self->state, in_data, (unsigned long)in_data_len);
56 if (rv != CRYPT_OK) croak("FATAL: ocb3_add_aad failed: %s", error_to_string(rv));
57 }
58 }
59
60 SV *
61 encrypt_add(Crypt::AuthEnc::OCB self, SV * data)
62 CODE:
63 {
64 int rv;
65 STRLEN in_data_len;
66 unsigned char *in_data, *out_data;
67
68 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
69 if (in_data_len==0) {
70 RETVAL = newSVpvn("", 0);
71 }
72 else {
73 RETVAL = NEWSV(0, in_data_len);
74 SvPOK_only(RETVAL);
75 SvCUR_set(RETVAL, in_data_len);
76 out_data = (unsigned char *)SvPV_nolen(RETVAL);
77
78 if (in_data_len % (&self->state)->block_len)
79 croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len);
80
81 rv = ocb3_encrypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
82 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt failed: %s", error_to_string(rv));
83 }
84 }
85 OUTPUT:
86 RETVAL
87
88 SV *
89 encrypt_last(Crypt::AuthEnc::OCB self, SV * data)
90 CODE:
91 {
92 int rv;
93 STRLEN in_data_len;
94 unsigned char *in_data, *out_data;
95
96 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
97 if (in_data_len>0) {
98 RETVAL = NEWSV(0, in_data_len);
99 SvPOK_only(RETVAL);
100 SvCUR_set(RETVAL, in_data_len);
101 out_data = (unsigned char *)SvPV_nolen(RETVAL);
102 }
103 else {
104 RETVAL = newSVpvn("", 0);
105 out_data = NULL;
106 }
107 rv = ocb3_encrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data);
108 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv));
109 }
110 OUTPUT:
111 RETVAL
112
113 SV *
114 decrypt_add(Crypt::AuthEnc::OCB self, SV * data)
115 CODE:
116 {
117 int rv;
118 STRLEN in_data_len;
119 unsigned char *in_data, *out_data;
120
121 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
122 if (in_data_len==0) {
123 RETVAL = newSVpvn("", 0);
124 }
125 else {
126 RETVAL = NEWSV(0, in_data_len);
127 SvPOK_only(RETVAL);
128 SvCUR_set(RETVAL, in_data_len);
129 out_data = (unsigned char *)SvPV_nolen(RETVAL);
130
131 if (in_data_len % (&self->state)->block_len)
132 croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len);
133
134 rv = ocb3_decrypt(&self->state, in_data, (unsigned long)in_data_len, out_data);
135 if (rv != CRYPT_OK) croak("FATAL: ocb3_decrypt failed: %s", error_to_string(rv));
136 }
137 }
138 OUTPUT:
139 RETVAL
140
141 SV *
142 decrypt_last(Crypt::AuthEnc::OCB self, SV * data)
143 CODE:
144 {
145 int rv;
146 STRLEN in_data_len;
147 unsigned char *in_data, *out_data;
148
149 in_data = (unsigned char *)SvPVbyte(data, in_data_len);
150 if (in_data_len>0) {
151 RETVAL = NEWSV(0, in_data_len);
152 SvPOK_only(RETVAL);
153 SvCUR_set(RETVAL, in_data_len);
154 out_data = (unsigned char *)SvPV_nolen(RETVAL);
155 }
156 else {
157 RETVAL = newSVpvn("", 0);
158 out_data = NULL;
159 }
160 rv = ocb3_decrypt_last(&self->state, in_data, (unsigned long)in_data_len, out_data);
161 if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv));
162 }
163 OUTPUT:
164 RETVAL
165
166 void
167 encrypt_done(Crypt::AuthEnc::OCB self)
168 PPCODE:
169 {
170 int rv;
171 unsigned char tag[MAXBLOCKSIZE];
172 unsigned long tag_len = sizeof(tag);
173
174 rv = ocb3_done(&self->state, tag, &tag_len);
175 if (rv != CRYPT_OK) croak("FATAL: ocb3_done_encrypt failed: %s", error_to_string(rv));
176
177 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
178 }
179
180 void
181 decrypt_done(Crypt::AuthEnc::OCB self, ...)
182 PPCODE:
183 {
184 int rv;
185 unsigned char tag[MAXBLOCKSIZE];
186 unsigned long tag_len = sizeof(tag);
187 STRLEN expected_tag_len;
188 unsigned char *expected_tag;
189
190 rv = ocb3_done(&self->state, tag, &tag_len);
191 if (rv != CRYPT_OK) croak("FATAL: ocb3_done_decrypt failed: %s", error_to_string(rv));
192 if (items == 1) {
193 XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len)));
194 }
195 else {
196 if(!SvPOK(ST(1))) croak("FATAL: expected_tag must be string/buffer scalar");
197 expected_tag = (unsigned char *) SvPVbyte(ST(1), expected_tag_len);
198 if (expected_tag_len!=tag_len) {
199 XPUSHs(sv_2mortal(newSViv(0))); /* false */
200 }
201 else if (memNE(expected_tag, tag, tag_len)) {
202 XPUSHs(sv_2mortal(newSViv(0))); /* false */
203 }
204 else {
205 XPUSHs(sv_2mortal(newSViv(1))); /* true */
206 }
207 }
208 }
209
210 int
211 blocksize(Crypt::AuthEnc::OCB self)
212 CODE:
213 {
214 RETVAL = (&self->state)->block_len;
215 }
216 OUTPUT:
217 RETVAL
0 MODULE = CryptX PACKAGE = Crypt::PK::DH
1
2 Crypt::PK::DH
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct dh_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::DH self, int key_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
27 rv = dh_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, &self->key);
28 if (rv != CRYPT_OK) croak("FATAL: dh_make_key failed: %s", error_to_string(rv));
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
33 _import(Crypt::PK::DH self, SV * key_data)
34 PPCODE:
35 {
36 int rv;
37 unsigned char *data=NULL;
38 STRLEN data_len=0;
39
40 data = (unsigned char *)SvPVbyte(key_data, data_len);
41 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
42 rv = dh_import(data, (unsigned long)data_len, &self->key);
43 if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv));
44 XPUSHs(ST(0)); /* return self */
45 }
46
47 int
48 is_private(Crypt::PK::DH self)
49 CODE:
50 if (self->key.type == -1) XSRETURN_UNDEF;
51 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
52 OUTPUT:
53 RETVAL
54
55 int
56 size(Crypt::PK::DH self)
57 CODE:
58 if (self->key.type == -1) XSRETURN_UNDEF;
59 RETVAL = dh_get_size(&self->key);
60 OUTPUT:
61 RETVAL
62
63 SV*
64 key2hash(Crypt::PK::DH self)
65 PREINIT:
66 HV *rv_hash;
67 long siz;
68 char buf[20001];
69 SV **not_used;
70 CODE:
71 if (self->key.type == -1) XSRETURN_UNDEF;
72 rv_hash = newHV();
73 /* =====> x */
74 siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0;
75 if (siz>10000) {
76 croak("FATAL: key2hash failed - 'x' too big number");
77 }
78 if (siz>0) {
79 mp_tohex(self->key.x, buf);
80 not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
81 }
82 else{
83 not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
84 }
85 /* =====> y */
86 siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0;
87 if (siz>10000) {
88 croak("FATAL: key2hash failed - 'y' too big number");
89 }
90 if (siz>0) {
91 mp_tohex(self->key.y, buf);
92 not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
93 }
94 else{
95 not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
96 }
97 /* =====> name */
98 snprintf(buf, sizeof(buf), "DH-%d", dh_get_size(&self->key)*8);
99 not_used = hv_store(rv_hash, "name", 4, newSVpv(buf, strlen(buf)), 0);
100 /* =====> size */
101 not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_size(&self->key)), 0);
102 /* =====> type */
103 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
104 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
105 RETVAL = newRV_noinc((SV*)rv_hash);
106 OUTPUT:
107 RETVAL
108
109 SV *
110 export_key(Crypt::PK::DH self, char * type)
111 CODE:
112 {
113 int rv;
114 unsigned char out[4096];
115 unsigned long int out_len = 4096;
116
117 RETVAL = newSVpvn(NULL, 0); /* undef */
118 if (strnEQ(type, "private", 7)) {
119 rv = dh_export(out, &out_len, PK_PRIVATE, &self->key);
120 if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PRIVATE) failed: %s", error_to_string(rv));
121 RETVAL = newSVpvn((char*)out, out_len);
122 }
123 else if (strnEQ(type, "public", 6)) {
124 rv = dh_export(out, &out_len, PK_PUBLIC, &self->key);
125 if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PUBLIC) failed: %s", error_to_string(rv));
126 RETVAL = newSVpvn((char*)out, out_len);
127 }
128 else {
129 croak("FATAL: export_key_der invalid type '%s'", type);
130 }
131 }
132 OUTPUT:
133 RETVAL
134
135 SV *
136 _encrypt(Crypt::PK::DH self, SV * data, char * hash_name)
137 CODE:
138 {
139 int rv, hash_id;
140 unsigned char *data_ptr=NULL;
141 STRLEN data_len=0;
142 unsigned char buffer[1024];
143 unsigned long buffer_len = 1024;
144
145 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
146
147 hash_id = find_hash(hash_name);
148 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
149 rv = dh_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
150 &self->yarrow_prng_state, self->yarrow_prng_index,
151 hash_id, &self->key);
152 if (rv != CRYPT_OK) croak("FATAL: dh_encrypt_key failed: %s", error_to_string(rv));
153 RETVAL = newSVpvn((char*)buffer, buffer_len);
154 }
155 OUTPUT:
156 RETVAL
157
158 SV *
159 _decrypt(Crypt::PK::DH self, SV * data)
160 CODE:
161 {
162 int rv;
163 unsigned char *data_ptr=NULL;
164 STRLEN data_len=0;
165 unsigned char buffer[1024];
166 unsigned long buffer_len = 1024;
167
168 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
169
170 rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
171 if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key_ex failed: %s", error_to_string(rv));
172 RETVAL = newSVpvn((char*)buffer, buffer_len);
173 }
174 OUTPUT:
175 RETVAL
176
177 SV *
178 _sign(Crypt::PK::DH self, SV * data)
179 CODE:
180 {
181 int rv;
182 unsigned char *data_ptr=NULL;
183 STRLEN data_len=0;
184 unsigned char buffer[1024];
185 unsigned long buffer_len = 1024;
186
187 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
188
189 rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
190 &self->yarrow_prng_state, self->yarrow_prng_index,
191 &self->key);
192 if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash_ex failed: %s", error_to_string(rv));
193 RETVAL = newSVpvn((char*)buffer, buffer_len);
194 }
195 OUTPUT:
196 RETVAL
197
198 int
199 _verify(Crypt::PK::DH self, SV * sig, SV * data)
200 CODE:
201 {
202 int rv, stat;
203 unsigned char *data_ptr=NULL;
204 STRLEN data_len=0;
205 unsigned char *sig_ptr=NULL;
206 STRLEN sig_len=0;
207
208 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
209 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
210
211 RETVAL = 1;
212 rv = dh_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
213 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
214 }
215 OUTPUT:
216 RETVAL
217
218 SV *
219 shared_secret(Crypt::PK::DH self, Crypt::PK::DH pubkey)
220 CODE:
221 {
222 int rv;
223 unsigned char buffer[1024];
224 unsigned long buffer_len = 1024;
225
226 rv = dh_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
227 if (rv != CRYPT_OK) croak("FATAL: dh_shared_secret failed: %s", error_to_string(rv));
228 RETVAL = newSVpvn((char*)buffer, buffer_len);
229 }
230 OUTPUT:
231 RETVAL
232
233 void
234 DESTROY(Crypt::PK::DH self)
235 CODE:
236 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
237 Safefree(self);
238
0 MODULE = CryptX PACKAGE = Crypt::PK::DH
1
2 Crypt::PK::DH
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct dh_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::DH self, int key_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
27 rv = dh_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, &self->key);
28 if (rv != CRYPT_OK) croak("FATAL: dh_make_key failed: %s", error_to_string(rv));
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
33 _import(Crypt::PK::DH self, SV * key_data)
34 PPCODE:
35 {
36 int rv;
37 unsigned char *data=NULL;
38 STRLEN data_len=0;
39
40 data = (unsigned char *)SvPVbyte(key_data, data_len);
41 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
42 rv = dh_import(data, (unsigned long)data_len, &self->key);
43 if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv));
44 XPUSHs(ST(0)); /* return self */
45 }
46
47 int
48 is_private(Crypt::PK::DH self)
49 CODE:
50 if (self->key.type == -1) XSRETURN_UNDEF;
51 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
52 OUTPUT:
53 RETVAL
54
55 int
56 size(Crypt::PK::DH self)
57 CODE:
58 if (self->key.type == -1) XSRETURN_UNDEF;
59 RETVAL = dh_get_size(&self->key);
60 OUTPUT:
61 RETVAL
62
63 SV*
64 key2hash(Crypt::PK::DH self)
65 PREINIT:
66 HV *rv_hash;
67 long siz;
68 char buf[20001];
69 SV **not_used;
70 CODE:
71 if (self->key.type == -1) XSRETURN_UNDEF;
72 rv_hash = newHV();
73 /* =====> x */
74 siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0;
75 if (siz>10000) {
76 croak("FATAL: key2hash failed - 'x' too big number");
77 }
78 if (siz>0) {
79 mp_tohex(self->key.x, buf);
80 not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
81 }
82 else{
83 not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
84 }
85 /* =====> y */
86 siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0;
87 if (siz>10000) {
88 croak("FATAL: key2hash failed - 'y' too big number");
89 }
90 if (siz>0) {
91 mp_tohex(self->key.y, buf);
92 not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
93 }
94 else{
95 not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
96 }
97 /* =====> name */
98 snprintf(buf, sizeof(buf), "DH-%d", dh_get_size(&self->key)*8);
99 not_used = hv_store(rv_hash, "name", 4, newSVpv(buf, strlen(buf)), 0);
100 /* =====> size */
101 not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_size(&self->key)), 0);
102 /* =====> type */
103 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
104 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
105 RETVAL = newRV_noinc((SV*)rv_hash);
106 OUTPUT:
107 RETVAL
108
109 SV *
110 export_key(Crypt::PK::DH self, char * type)
111 CODE:
112 {
113 int rv;
114 unsigned char out[4096];
115 unsigned long int out_len = 4096;
116
117 RETVAL = newSVpvn(NULL, 0); /* undef */
118 if (strnEQ(type, "private", 7)) {
119 rv = dh_export(out, &out_len, PK_PRIVATE, &self->key);
120 if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PRIVATE) failed: %s", error_to_string(rv));
121 RETVAL = newSVpvn((char*)out, out_len);
122 }
123 else if (strnEQ(type, "public", 6)) {
124 rv = dh_export(out, &out_len, PK_PUBLIC, &self->key);
125 if (rv != CRYPT_OK) croak("FATAL: dh_export(PK_PUBLIC) failed: %s", error_to_string(rv));
126 RETVAL = newSVpvn((char*)out, out_len);
127 }
128 else {
129 croak("FATAL: export_key_der invalid type '%s'", type);
130 }
131 }
132 OUTPUT:
133 RETVAL
134
135 SV *
136 _encrypt(Crypt::PK::DH self, SV * data, char * hash_name)
137 CODE:
138 {
139 int rv, hash_id;
140 unsigned char *data_ptr=NULL;
141 STRLEN data_len=0;
142 unsigned char buffer[1024];
143 unsigned long buffer_len = 1024;
144
145 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
146
147 hash_id = find_hash(hash_name);
148 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
149 rv = dh_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
150 &self->yarrow_prng_state, self->yarrow_prng_index,
151 hash_id, &self->key);
152 if (rv != CRYPT_OK) croak("FATAL: dh_encrypt_key failed: %s", error_to_string(rv));
153 RETVAL = newSVpvn((char*)buffer, buffer_len);
154 }
155 OUTPUT:
156 RETVAL
157
158 SV *
159 _decrypt(Crypt::PK::DH self, SV * data)
160 CODE:
161 {
162 int rv;
163 unsigned char *data_ptr=NULL;
164 STRLEN data_len=0;
165 unsigned char buffer[1024];
166 unsigned long buffer_len = 1024;
167
168 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
169
170 rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
171 if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key_ex failed: %s", error_to_string(rv));
172 RETVAL = newSVpvn((char*)buffer, buffer_len);
173 }
174 OUTPUT:
175 RETVAL
176
177 SV *
178 _sign(Crypt::PK::DH self, SV * data)
179 CODE:
180 {
181 int rv;
182 unsigned char *data_ptr=NULL;
183 STRLEN data_len=0;
184 unsigned char buffer[1024];
185 unsigned long buffer_len = 1024;
186
187 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
188
189 rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
190 &self->yarrow_prng_state, self->yarrow_prng_index,
191 &self->key);
192 if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash_ex failed: %s", error_to_string(rv));
193 RETVAL = newSVpvn((char*)buffer, buffer_len);
194 }
195 OUTPUT:
196 RETVAL
197
198 int
199 _verify(Crypt::PK::DH self, SV * sig, SV * data)
200 CODE:
201 {
202 int rv, stat;
203 unsigned char *data_ptr=NULL;
204 STRLEN data_len=0;
205 unsigned char *sig_ptr=NULL;
206 STRLEN sig_len=0;
207
208 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
209 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
210
211 RETVAL = 1;
212 rv = dh_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
213 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
214 }
215 OUTPUT:
216 RETVAL
217
218 SV *
219 shared_secret(Crypt::PK::DH self, Crypt::PK::DH pubkey)
220 CODE:
221 {
222 int rv;
223 unsigned char buffer[1024];
224 unsigned long buffer_len = 1024;
225
226 rv = dh_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
227 if (rv != CRYPT_OK) croak("FATAL: dh_shared_secret failed: %s", error_to_string(rv));
228 RETVAL = newSVpvn((char*)buffer, buffer_len);
229 }
230 OUTPUT:
231 RETVAL
232
233 void
234 DESTROY(Crypt::PK::DH self)
235 CODE:
236 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
237 Safefree(self);
238
0 MODULE = CryptX PACKAGE = Crypt::PK::DSA
1
2 Crypt::PK::DSA
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct dsa_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
27 rv = dsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, group_size, modulus_size, &self->key);
28 if (rv != CRYPT_OK) croak("FATAL: dsa_make_key failed: %s", error_to_string(rv));
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
33 _import(Crypt::PK::DSA self, SV * key_data)
34 PPCODE:
35 {
36 int rv;
37 unsigned char *data=NULL;
38 STRLEN data_len=0;
39
40 data = (unsigned char *)SvPVbyte(key_data, data_len);
41 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
42 rv = dsa_import(data, (unsigned long)data_len, &self->key);
43 if (rv != CRYPT_OK) croak("FATAL: dsa_import failed: %s", error_to_string(rv));
44 XPUSHs(ST(0)); /* return self */
45 }
46
47 void
48 _import_hex(Crypt::PK::DSA self, char *p, char *q, char *g, char *x, char *y)
49 PPCODE:
50 {
51 int rv;
52 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
53 rv = dsa_import_hex(p, q, g, x, y, &self->key);
54 if (rv != CRYPT_OK) croak("FATAL: dsa_import_hex failed: %s", error_to_string(rv));
55 XPUSHs(ST(0)); /* return self */
56 }
57
58 int
59 is_private(Crypt::PK::DSA self)
60 CODE:
61 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
62 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
63 OUTPUT:
64 RETVAL
65
66 int
67 size(Crypt::PK::DSA self)
68 CODE:
69 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
70 RETVAL = mp_unsigned_bin_size(self->key.g);
71 OUTPUT:
72 RETVAL
73
74 int
75 size_q(Crypt::PK::DSA self)
76 CODE:
77 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
78 RETVAL = self->key.qord;
79 OUTPUT:
80 RETVAL
81
82 SV*
83 key2hash(Crypt::PK::DSA self)
84 PREINIT:
85 HV *rv_hash;
86 long siz;
87 char buf[20001];
88 SV **not_used;
89 CODE:
90 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
91 rv_hash = newHV();
92 /* =====> g */
93 siz = (self->key.g) ? mp_unsigned_bin_size(self->key.g) : 0;
94 if (siz>10000) {
95 croak("FATAL: key2hash failed - 'g' too big number");
96 }
97 if (siz>0) {
98 mp_tohex(self->key.g, buf);
99 not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
100 }
101 else{
102 not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
103 }
104 /* =====> q */
105 siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0;
106 if (siz>10000) {
107 croak("FATAL: key2hash failed - 'q' too big number");
108 }
109 if (siz>0) {
110 mp_tohex(self->key.q, buf);
111 not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
112 }
113 else{
114 not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
115 }
116 /* =====> p */
117 siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0;
118 if (siz>10000) {
119 croak("FATAL: key2hash failed - 'p' too big number");
120 }
121 if (siz>0) {
122 mp_tohex(self->key.p, buf);
123 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
124 }
125 else{
126 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
127 }
128 /* =====> x */
129 siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0;
130 if (siz>10000) {
131 croak("FATAL: key2hash failed - 'x' too big number");
132 }
133 if (siz>0) {
134 mp_tohex(self->key.x, buf);
135 not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
136 }
137 else{
138 not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
139 }
140 /* =====> y */
141 siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0;
142 if (siz>10000) {
143 croak("FATAL: key2hash failed - 'y' too big number");
144 }
145 if (siz>0) {
146 mp_tohex(self->key.y, buf);
147 not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
148 }
149 else{
150 not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
151 }
152 /* =====> size */
153 not_used = hv_store(rv_hash, "size", 4, newSViv(mp_unsigned_bin_size(self->key.q)), 0);
154 /* =====> type */
155 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
156 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
157 RETVAL = newRV_noinc((SV*)rv_hash);
158 OUTPUT:
159 RETVAL
160
161 SV *
162 export_key_der(Crypt::PK::DSA self, char * type)
163 CODE:
164 {
165 int rv;
166 unsigned char out[4096];
167 unsigned long int out_len = 4096;
168
169 RETVAL = newSVpvn(NULL, 0); /* undef */
170 if (strnEQ(type, "private", 7)) {
171 rv = dsa_export(out, &out_len, PK_PRIVATE, &self->key);
172 if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PRIVATE) failed: %s", error_to_string(rv));
173 RETVAL = newSVpvn((char*)out, out_len);
174 }
175 else if (strnEQ(type, "public", 6)) {
176 rv = dsa_export(out, &out_len, PK_PUBLIC, &self->key);
177 if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PUBLIC) failed: %s", error_to_string(rv));
178 RETVAL = newSVpvn((char*)out, out_len);
179 }
180 else {
181 croak("FATAL: export_key_der invalid type '%s'", type);
182 }
183 }
184 OUTPUT:
185 RETVAL
186
187 SV *
188 _encrypt(Crypt::PK::DSA self, SV * data, char * hash_name)
189 CODE:
190 {
191 int rv, hash_id;
192 unsigned char *data_ptr=NULL;
193 STRLEN data_len=0;
194 unsigned char buffer[1024];
195 unsigned long buffer_len = 1024;
196
197 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
198
199 hash_id = find_hash(hash_name);
200 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
201 rv = dsa_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
202 &self->yarrow_prng_state, self->yarrow_prng_index,
203 hash_id, &self->key);
204 if (rv != CRYPT_OK) croak("FATAL: dsa_encrypt_key failed: %s", error_to_string(rv));
205 RETVAL = newSVpvn((char*)buffer, buffer_len);
206 }
207 OUTPUT:
208 RETVAL
209
210 SV *
211 _decrypt(Crypt::PK::DSA self, SV * data)
212 CODE:
213 {
214 int rv;
215 unsigned char *data_ptr=NULL;
216 STRLEN data_len=0;
217 unsigned char buffer[1024];
218 unsigned long buffer_len = 1024;
219
220 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
221
222 rv = dsa_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
223 if (rv != CRYPT_OK) croak("FATAL: dsa_decrypt_key_ex failed: %s", error_to_string(rv));
224 RETVAL = newSVpvn((char*)buffer, buffer_len);
225 }
226 OUTPUT:
227 RETVAL
228
229 SV *
230 _sign(Crypt::PK::DSA self, SV * data)
231 CODE:
232 {
233 int rv;
234 unsigned char *data_ptr=NULL;
235 STRLEN data_len=0;
236 unsigned char buffer[1024];
237 unsigned long buffer_len = 1024;
238
239 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
240
241 rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
242 &self->yarrow_prng_state, self->yarrow_prng_index,
243 &self->key);
244 if (rv != CRYPT_OK) croak("FATAL: dsa_sign_hash_ex failed: %s", error_to_string(rv));
245 RETVAL = newSVpvn((char*)buffer, buffer_len);
246 }
247 OUTPUT:
248 RETVAL
249
250 int
251 _verify(Crypt::PK::DSA self, SV * sig, SV * data)
252 CODE:
253 {
254 int rv, stat;
255 unsigned char *data_ptr=NULL;
256 STRLEN data_len=0;
257 unsigned char *sig_ptr=NULL;
258 STRLEN sig_len=0;
259
260 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
261 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
262
263 RETVAL = 1;
264 rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
265 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
266 }
267 OUTPUT:
268 RETVAL
269
270 void
271 DESTROY(Crypt::PK::DSA self)
272 CODE:
273 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
274 Safefree(self);
275
0 MODULE = CryptX PACKAGE = Crypt::PK::DSA
1
2 Crypt::PK::DSA
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct dsa_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
27 rv = dsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, group_size, modulus_size, &self->key);
28 if (rv != CRYPT_OK) croak("FATAL: dsa_make_key failed: %s", error_to_string(rv));
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
33 _import(Crypt::PK::DSA self, SV * key_data)
34 PPCODE:
35 {
36 int rv;
37 unsigned char *data=NULL;
38 STRLEN data_len=0;
39
40 data = (unsigned char *)SvPVbyte(key_data, data_len);
41 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
42 rv = dsa_import(data, (unsigned long)data_len, &self->key);
43 if (rv != CRYPT_OK) croak("FATAL: dsa_import failed: %s", error_to_string(rv));
44 XPUSHs(ST(0)); /* return self */
45 }
46
47 void
48 _import_hex(Crypt::PK::DSA self, char *p, char *q, char *g, char *x, char *y)
49 PPCODE:
50 {
51 int rv;
52 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
53 rv = dsa_import_hex(p, q, g, x, y, &self->key);
54 if (rv != CRYPT_OK) croak("FATAL: dsa_import_hex failed: %s", error_to_string(rv));
55 XPUSHs(ST(0)); /* return self */
56 }
57
58 int
59 is_private(Crypt::PK::DSA self)
60 CODE:
61 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
62 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
63 OUTPUT:
64 RETVAL
65
66 int
67 size(Crypt::PK::DSA self)
68 CODE:
69 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
70 RETVAL = mp_unsigned_bin_size(self->key.g);
71 OUTPUT:
72 RETVAL
73
74 int
75 size_q(Crypt::PK::DSA self)
76 CODE:
77 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
78 RETVAL = self->key.qord;
79 OUTPUT:
80 RETVAL
81
82 SV*
83 key2hash(Crypt::PK::DSA self)
84 PREINIT:
85 HV *rv_hash;
86 long siz;
87 char buf[20001];
88 SV **not_used;
89 CODE:
90 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
91 rv_hash = newHV();
92 /* =====> g */
93 siz = (self->key.g) ? mp_unsigned_bin_size(self->key.g) : 0;
94 if (siz>10000) {
95 croak("FATAL: key2hash failed - 'g' too big number");
96 }
97 if (siz>0) {
98 mp_tohex(self->key.g, buf);
99 not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
100 }
101 else{
102 not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
103 }
104 /* =====> q */
105 siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0;
106 if (siz>10000) {
107 croak("FATAL: key2hash failed - 'q' too big number");
108 }
109 if (siz>0) {
110 mp_tohex(self->key.q, buf);
111 not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
112 }
113 else{
114 not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
115 }
116 /* =====> p */
117 siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0;
118 if (siz>10000) {
119 croak("FATAL: key2hash failed - 'p' too big number");
120 }
121 if (siz>0) {
122 mp_tohex(self->key.p, buf);
123 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
124 }
125 else{
126 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
127 }
128 /* =====> x */
129 siz = (self->key.x) ? mp_unsigned_bin_size(self->key.x) : 0;
130 if (siz>10000) {
131 croak("FATAL: key2hash failed - 'x' too big number");
132 }
133 if (siz>0) {
134 mp_tohex(self->key.x, buf);
135 not_used = hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
136 }
137 else{
138 not_used = hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
139 }
140 /* =====> y */
141 siz = (self->key.y) ? mp_unsigned_bin_size(self->key.y) : 0;
142 if (siz>10000) {
143 croak("FATAL: key2hash failed - 'y' too big number");
144 }
145 if (siz>0) {
146 mp_tohex(self->key.y, buf);
147 not_used = hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
148 }
149 else{
150 not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
151 }
152 /* =====> size */
153 not_used = hv_store(rv_hash, "size", 4, newSViv(mp_unsigned_bin_size(self->key.q)), 0);
154 /* =====> type */
155 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
156 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
157 RETVAL = newRV_noinc((SV*)rv_hash);
158 OUTPUT:
159 RETVAL
160
161 SV *
162 export_key_der(Crypt::PK::DSA self, char * type)
163 CODE:
164 {
165 int rv;
166 unsigned char out[4096];
167 unsigned long int out_len = 4096;
168
169 RETVAL = newSVpvn(NULL, 0); /* undef */
170 if (strnEQ(type, "private", 7)) {
171 rv = dsa_export(out, &out_len, PK_PRIVATE, &self->key);
172 if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PRIVATE) failed: %s", error_to_string(rv));
173 RETVAL = newSVpvn((char*)out, out_len);
174 }
175 else if (strnEQ(type, "public", 6)) {
176 rv = dsa_export(out, &out_len, PK_PUBLIC, &self->key);
177 if (rv != CRYPT_OK) croak("FATAL: dsa_export(PK_PUBLIC) failed: %s", error_to_string(rv));
178 RETVAL = newSVpvn((char*)out, out_len);
179 }
180 else {
181 croak("FATAL: export_key_der invalid type '%s'", type);
182 }
183 }
184 OUTPUT:
185 RETVAL
186
187 SV *
188 _encrypt(Crypt::PK::DSA self, SV * data, char * hash_name)
189 CODE:
190 {
191 int rv, hash_id;
192 unsigned char *data_ptr=NULL;
193 STRLEN data_len=0;
194 unsigned char buffer[1024];
195 unsigned long buffer_len = 1024;
196
197 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
198
199 hash_id = find_hash(hash_name);
200 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
201 rv = dsa_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
202 &self->yarrow_prng_state, self->yarrow_prng_index,
203 hash_id, &self->key);
204 if (rv != CRYPT_OK) croak("FATAL: dsa_encrypt_key failed: %s", error_to_string(rv));
205 RETVAL = newSVpvn((char*)buffer, buffer_len);
206 }
207 OUTPUT:
208 RETVAL
209
210 SV *
211 _decrypt(Crypt::PK::DSA self, SV * data)
212 CODE:
213 {
214 int rv;
215 unsigned char *data_ptr=NULL;
216 STRLEN data_len=0;
217 unsigned char buffer[1024];
218 unsigned long buffer_len = 1024;
219
220 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
221
222 rv = dsa_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
223 if (rv != CRYPT_OK) croak("FATAL: dsa_decrypt_key_ex failed: %s", error_to_string(rv));
224 RETVAL = newSVpvn((char*)buffer, buffer_len);
225 }
226 OUTPUT:
227 RETVAL
228
229 SV *
230 _sign(Crypt::PK::DSA self, SV * data)
231 CODE:
232 {
233 int rv;
234 unsigned char *data_ptr=NULL;
235 STRLEN data_len=0;
236 unsigned char buffer[1024];
237 unsigned long buffer_len = 1024;
238
239 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
240
241 rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
242 &self->yarrow_prng_state, self->yarrow_prng_index,
243 &self->key);
244 if (rv != CRYPT_OK) croak("FATAL: dsa_sign_hash_ex failed: %s", error_to_string(rv));
245 RETVAL = newSVpvn((char*)buffer, buffer_len);
246 }
247 OUTPUT:
248 RETVAL
249
250 int
251 _verify(Crypt::PK::DSA self, SV * sig, SV * data)
252 CODE:
253 {
254 int rv, stat;
255 unsigned char *data_ptr=NULL;
256 STRLEN data_len=0;
257 unsigned char *sig_ptr=NULL;
258 STRLEN sig_len=0;
259
260 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
261 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
262
263 RETVAL = 1;
264 rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
265 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
266 }
267 OUTPUT:
268 RETVAL
269
270 void
271 DESTROY(Crypt::PK::DSA self)
272 CODE:
273 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
274 Safefree(self);
275
0 MODULE = CryptX PACKAGE = Crypt::PK::ECC
1
2 Crypt::PK::ECC
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct ecc_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->yarrow_prng_index = find_prng("yarrow");
10 RETVAL->key.type = -1;
11 ecc_dp_init(&RETVAL->dp);
12 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
13 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
14 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
15 }
16 OUTPUT:
17 RETVAL
18
19 void
20 generate_key(Crypt::PK::ECC self, SV *curve)
21 PPCODE:
22 {
23 int rv;
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* setup dp structure */
28 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
29 /* gen the key */
30 rv = ecc_make_key_ex(&self->yarrow_prng_state, self->yarrow_prng_index, &self->key, &self->dp);
31 if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv));
32 XPUSHs(ST(0)); /* return self */
33 }
34
35 void
36 _import(Crypt::PK::ECC self, SV * key_data)
37 PPCODE:
38 {
39 int rv;
40 unsigned char *data=NULL;
41 STRLEN data_len=0;
42
43 data = (unsigned char *)SvPVbyte(key_data, data_len);
44 _ecc_free_key(&self->key, &self->dp);
45 rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp);
46 if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv));
47 XPUSHs(ST(0)); /* return self */
48 }
49
50 void
51 _import_pkcs8(Crypt::PK::ECC self, SV * key_data)
52 PPCODE:
53 {
54 int rv;
55 unsigned char *data=NULL;
56 STRLEN data_len=0;
57
58 data = (unsigned char *)SvPVbyte(key_data, data_len);
59 _ecc_free_key(&self->key, &self->dp);
60 rv = ecc_import_pkcs8(data, (unsigned long)data_len, &self->key, &self->dp);
61 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
62 XPUSHs(ST(0)); /* return self */
63 }
64
65 void
66 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
67 PPCODE:
68 {
69 int rv;
70 unsigned char *data=NULL;
71 STRLEN data_len=0;
72
73 data = (unsigned char *)SvPVbyte(key_data, data_len);
74 _ecc_free_key(&self->key, &self->dp);
75
76 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
77
78 rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp);
79 if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv));
80 XPUSHs(ST(0)); /* return self */
81 }
82
83 int
84 is_private(Crypt::PK::ECC self)
85 CODE:
86 if (self->key.type == -1) XSRETURN_UNDEF;
87 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
88 OUTPUT:
89 RETVAL
90
91 int
92 size(Crypt::PK::ECC self)
93 CODE:
94 if (self->key.type == -1) XSRETURN_UNDEF;
95 RETVAL = ecc_get_size(&self->key);
96 OUTPUT:
97 RETVAL
98
99 SV*
100 key2hash(Crypt::PK::ECC self)
101 PREINIT:
102 HV *rv_hash;
103 long siz;
104 char buf[20001];
105 SV **not_used;
106 CODE:
107 if (self->key.type == -1) XSRETURN_UNDEF;
108 rv_hash = newHV();
109 /* =====> k */
110 siz = (self->key.k) ? mp_unsigned_bin_size(self->key.k) : 0;
111 if (siz>10000) {
112 croak("FATAL: key2hash failed - 'k' too big number");
113 }
114 if (siz>0) {
115 mp_tohex(self->key.k, buf);
116 not_used = hv_store(rv_hash, "k", 1, newSVpv(buf, strlen(buf)), 0);
117 }
118 else{
119 not_used = hv_store(rv_hash, "k", 1, newSVpv("", 0), 0);
120 }
121 /* =====> pub_x */
122 siz = (self->key.pubkey.x) ? mp_unsigned_bin_size(self->key.pubkey.x) : 0;
123 if (siz>10000) {
124 croak("FATAL: key2hash failed - 'pub_x' too big number");
125 }
126 if (siz>0) {
127 mp_tohex(self->key.pubkey.x, buf);
128 not_used = hv_store(rv_hash, "pub_x", 5, newSVpv(buf, strlen(buf)), 0);
129 }
130 else{
131 not_used = hv_store(rv_hash, "pub_x", 5, newSVpv("", 0), 0);
132 }
133 /* =====> pub_y */
134 siz = (self->key.pubkey.y) ? mp_unsigned_bin_size(self->key.pubkey.y) : 0;
135 if (siz>10000) {
136 croak("FATAL: key2hash failed - 'pub_y' too big number");
137 }
138 if (siz>0) {
139 mp_tohex(self->key.pubkey.y, buf);
140 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv(buf, strlen(buf)), 0);
141 }
142 else{
143 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0);
144 }
145 /* =====> curve_... */
146 if (self->key.dp) {
147 not_used = hv_store(rv_hash, "curve_name", 10, newSVpv(self->key.dp->name, strlen(self->key.dp->name)), 0);
148 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0);
149 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0);
150 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0);
151 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0);
152 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0);
153 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0);
154 not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0);
155 {
156 mp_int p_num;
157 mp_init(&p_num);
158 mp_read_radix(&p_num, self->key.dp->prime, 16);
159 not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0);
160 not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0);
161 mp_clear(&p_num);
162 }
163 }
164 /* =====> size */
165 not_used = hv_store(rv_hash, "size", 4, newSViv(ecc_get_size(&self->key)), 0);
166 /* =====> type */
167 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
168 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
169 RETVAL = newRV_noinc((SV*)rv_hash);
170 OUTPUT:
171 RETVAL
172
173 SV *
174 export_key_der(Crypt::PK::ECC self, char * type)
175 CODE:
176 {
177 int rv;
178 unsigned char out[4096];
179 unsigned long int out_len = 4096;
180
181 RETVAL = newSVpvn(NULL, 0); /* undef */
182 if (strnEQ(type, "private", 7)) {
183 rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key);
184 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv));
185 RETVAL = newSVpvn((char*)out, out_len);
186 }
187 else if (strnEQ(type, "public", 6)) {
188 rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key);
189 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv));
190 RETVAL = newSVpvn((char*)out, out_len);
191 }
192 else {
193 croak("FATAL: export_key_der invalid type '%s'", type);
194 }
195 }
196 OUTPUT:
197 RETVAL
198
199 SV *
200 export_key_raw(Crypt::PK::ECC self, char * type)
201 CODE:
202 {
203 int rv;
204 unsigned char out[4096];
205 unsigned long int out_len = sizeof(out);
206
207 RETVAL = newSVpvn(NULL, 0); /* undef */
208 if (strnEQ(type, "private", 7)) {
209 rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key);
210 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv));
211 RETVAL = newSVpvn((char*)out, out_len);
212 }
213 else if (strnEQ(type, "public_compressed", 17)) {
214 rv = ecc_export_raw(out, &out_len, PK_PUBLIC_COMPRESSED, &self->key);
215 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv));
216 RETVAL = newSVpvn((char*)out, out_len);
217 }
218 else if (strnEQ(type, "public", 6)) {
219 rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key);
220 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv));
221 RETVAL = newSVpvn((char*)out, out_len);
222 }
223 else {
224 croak("FATAL: export_key_raw invalid type '%s'", type);
225 }
226 }
227 OUTPUT:
228 RETVAL
229
230 SV *
231 _encrypt(Crypt::PK::ECC self, SV * data, char * hash_name)
232 CODE:
233 {
234 int rv, hash_id;
235 unsigned char *data_ptr=NULL;
236 STRLEN data_len=0;
237 unsigned char buffer[1024];
238 unsigned long buffer_len = 1024;
239
240 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
241
242 hash_id = find_hash(hash_name);
243 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
244 rv = ecc_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
245 &self->yarrow_prng_state, self->yarrow_prng_index,
246 hash_id, &self->key);
247 if (rv != CRYPT_OK) croak("FATAL: ecc_encrypt_key failed: %s", error_to_string(rv));
248 RETVAL = newSVpvn((char*)buffer, buffer_len);
249 }
250 OUTPUT:
251 RETVAL
252
253 SV *
254 _decrypt(Crypt::PK::ECC self, SV * data)
255 CODE:
256 {
257 int rv;
258 unsigned char *data_ptr=NULL;
259 STRLEN data_len=0;
260 unsigned char buffer[1024];
261 unsigned long buffer_len = 1024;
262
263 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
264
265 rv = ecc_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
266 if (rv != CRYPT_OK) croak("FATAL: ecc_decrypt_key_ex failed: %s", error_to_string(rv));
267 RETVAL = newSVpvn((char*)buffer, buffer_len);
268 }
269 OUTPUT:
270 RETVAL
271
272 SV *
273 _sign(Crypt::PK::ECC self, SV * data)
274 ALIAS:
275 _sign_rfc7518 = 1
276 CODE:
277 {
278 int rv;
279 unsigned char *data_ptr=NULL;
280 STRLEN data_len=0;
281 unsigned char buffer[1024];
282 unsigned long buffer_len = 1024;
283
284 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
285
286 if (ix == 1) {
287 rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
288 &self->yarrow_prng_state, self->yarrow_prng_index,
289 &self->key);
290 }
291 else {
292 rv = ecc_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
293 &self->yarrow_prng_state, self->yarrow_prng_index,
294 &self->key);
295 }
296 if (rv != CRYPT_OK) croak("FATAL: ecc_sign_hash_ex failed: %s", error_to_string(rv));
297 RETVAL = newSVpvn((char*)buffer, buffer_len);
298 }
299 OUTPUT:
300 RETVAL
301
302 int
303 _verify(Crypt::PK::ECC self, SV * sig, SV * data)
304 ALIAS:
305 _verify_rfc7518 = 1
306 CODE:
307 {
308 int rv, stat;
309 unsigned char *data_ptr=NULL;
310 STRLEN data_len=0;
311 unsigned char *sig_ptr=NULL;
312 STRLEN sig_len=0;
313
314 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
315 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
316
317 RETVAL = 1;
318 if (ix == 1) {
319 rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
320 }
321 else {
322 rv = ecc_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
323 }
324 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
325 }
326 OUTPUT:
327 RETVAL
328
329 SV *
330 shared_secret(Crypt::PK::ECC self, Crypt::PK::ECC pubkey)
331 CODE:
332 {
333 int rv;
334 unsigned char buffer[1024];
335 unsigned long buffer_len = 1024;
336
337 rv = ecc_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
338 if (rv != CRYPT_OK) croak("FATAL: ecc_shared_secret failed: %s", error_to_string(rv));
339 RETVAL = newSVpvn((char*)buffer, buffer_len);
340 }
341 OUTPUT:
342 RETVAL
343
344 void
345 DESTROY(Crypt::PK::ECC self)
346 CODE:
347 _ecc_free_key(&self->key, &self->dp);
348 Safefree(self);
349
0 MODULE = CryptX PACKAGE = Crypt::PK::ECC
1
2 Crypt::PK::ECC
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct ecc_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->yarrow_prng_index = find_prng("yarrow");
10 RETVAL->key.type = -1;
11 ecc_dp_init(&RETVAL->dp);
12 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
13 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
14 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
15 }
16 OUTPUT:
17 RETVAL
18
19 void
20 generate_key(Crypt::PK::ECC self, SV *curve)
21 PPCODE:
22 {
23 int rv;
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* setup dp structure */
28 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
29 /* gen the key */
30 rv = ecc_make_key_ex(&self->yarrow_prng_state, self->yarrow_prng_index, &self->key, &self->dp);
31 if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv));
32 XPUSHs(ST(0)); /* return self */
33 }
34
35 void
36 _import(Crypt::PK::ECC self, SV * key_data)
37 PPCODE:
38 {
39 int rv;
40 unsigned char *data=NULL;
41 STRLEN data_len=0;
42
43 data = (unsigned char *)SvPVbyte(key_data, data_len);
44 _ecc_free_key(&self->key, &self->dp);
45 rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp);
46 if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv));
47 XPUSHs(ST(0)); /* return self */
48 }
49
50 void
51 _import_pkcs8(Crypt::PK::ECC self, SV * key_data)
52 PPCODE:
53 {
54 int rv;
55 unsigned char *data=NULL;
56 STRLEN data_len=0;
57
58 data = (unsigned char *)SvPVbyte(key_data, data_len);
59 _ecc_free_key(&self->key, &self->dp);
60 rv = ecc_import_pkcs8(data, (unsigned long)data_len, &self->key, &self->dp);
61 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
62 XPUSHs(ST(0)); /* return self */
63 }
64
65 void
66 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
67 PPCODE:
68 {
69 int rv;
70 unsigned char *data=NULL;
71 STRLEN data_len=0;
72
73 data = (unsigned char *)SvPVbyte(key_data, data_len);
74 _ecc_free_key(&self->key, &self->dp);
75
76 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
77
78 rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp);
79 if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv));
80 XPUSHs(ST(0)); /* return self */
81 }
82
83 int
84 is_private(Crypt::PK::ECC self)
85 CODE:
86 if (self->key.type == -1) XSRETURN_UNDEF;
87 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
88 OUTPUT:
89 RETVAL
90
91 int
92 size(Crypt::PK::ECC self)
93 CODE:
94 if (self->key.type == -1) XSRETURN_UNDEF;
95 RETVAL = ecc_get_size(&self->key);
96 OUTPUT:
97 RETVAL
98
99 SV*
100 key2hash(Crypt::PK::ECC self)
101 PREINIT:
102 HV *rv_hash;
103 long siz;
104 char buf[20001];
105 SV **not_used;
106 CODE:
107 if (self->key.type == -1) XSRETURN_UNDEF;
108 rv_hash = newHV();
109 /* =====> k */
110 siz = (self->key.k) ? mp_unsigned_bin_size(self->key.k) : 0;
111 if (siz>10000) {
112 croak("FATAL: key2hash failed - 'k' too big number");
113 }
114 if (siz>0) {
115 mp_tohex(self->key.k, buf);
116 not_used = hv_store(rv_hash, "k", 1, newSVpv(buf, strlen(buf)), 0);
117 }
118 else{
119 not_used = hv_store(rv_hash, "k", 1, newSVpv("", 0), 0);
120 }
121 /* =====> pub_x */
122 siz = (self->key.pubkey.x) ? mp_unsigned_bin_size(self->key.pubkey.x) : 0;
123 if (siz>10000) {
124 croak("FATAL: key2hash failed - 'pub_x' too big number");
125 }
126 if (siz>0) {
127 mp_tohex(self->key.pubkey.x, buf);
128 not_used = hv_store(rv_hash, "pub_x", 5, newSVpv(buf, strlen(buf)), 0);
129 }
130 else{
131 not_used = hv_store(rv_hash, "pub_x", 5, newSVpv("", 0), 0);
132 }
133 /* =====> pub_y */
134 siz = (self->key.pubkey.y) ? mp_unsigned_bin_size(self->key.pubkey.y) : 0;
135 if (siz>10000) {
136 croak("FATAL: key2hash failed - 'pub_y' too big number");
137 }
138 if (siz>0) {
139 mp_tohex(self->key.pubkey.y, buf);
140 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv(buf, strlen(buf)), 0);
141 }
142 else{
143 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0);
144 }
145 /* =====> curve_... */
146 if (self->key.dp) {
147 not_used = hv_store(rv_hash, "curve_name", 10, newSVpv(self->key.dp->name, strlen(self->key.dp->name)), 0);
148 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0);
149 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0);
150 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0);
151 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0);
152 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0);
153 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0);
154 not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0);
155 {
156 mp_int p_num;
157 mp_init(&p_num);
158 mp_read_radix(&p_num, self->key.dp->prime, 16);
159 not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0);
160 not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0);
161 mp_clear(&p_num);
162 }
163 }
164 /* =====> size */
165 not_used = hv_store(rv_hash, "size", 4, newSViv(ecc_get_size(&self->key)), 0);
166 /* =====> type */
167 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
168 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
169 RETVAL = newRV_noinc((SV*)rv_hash);
170 OUTPUT:
171 RETVAL
172
173 SV *
174 export_key_der(Crypt::PK::ECC self, char * type)
175 CODE:
176 {
177 int rv;
178 unsigned char out[4096];
179 unsigned long int out_len = 4096;
180
181 RETVAL = newSVpvn(NULL, 0); /* undef */
182 if (strnEQ(type, "private", 7)) {
183 rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key);
184 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv));
185 RETVAL = newSVpvn((char*)out, out_len);
186 }
187 else if (strnEQ(type, "public", 6)) {
188 rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key);
189 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv));
190 RETVAL = newSVpvn((char*)out, out_len);
191 }
192 else {
193 croak("FATAL: export_key_der invalid type '%s'", type);
194 }
195 }
196 OUTPUT:
197 RETVAL
198
199 SV *
200 export_key_raw(Crypt::PK::ECC self, char * type)
201 CODE:
202 {
203 int rv;
204 unsigned char out[4096];
205 unsigned long int out_len = sizeof(out);
206
207 RETVAL = newSVpvn(NULL, 0); /* undef */
208 if (strnEQ(type, "private", 7)) {
209 rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key);
210 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv));
211 RETVAL = newSVpvn((char*)out, out_len);
212 }
213 else if (strnEQ(type, "public_compressed", 17)) {
214 rv = ecc_export_raw(out, &out_len, PK_PUBLIC_COMPRESSED, &self->key);
215 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv));
216 RETVAL = newSVpvn((char*)out, out_len);
217 }
218 else if (strnEQ(type, "public", 6)) {
219 rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key);
220 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv));
221 RETVAL = newSVpvn((char*)out, out_len);
222 }
223 else {
224 croak("FATAL: export_key_raw invalid type '%s'", type);
225 }
226 }
227 OUTPUT:
228 RETVAL
229
230 SV *
231 _encrypt(Crypt::PK::ECC self, SV * data, char * hash_name)
232 CODE:
233 {
234 int rv, hash_id;
235 unsigned char *data_ptr=NULL;
236 STRLEN data_len=0;
237 unsigned char buffer[1024];
238 unsigned long buffer_len = 1024;
239
240 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
241
242 hash_id = find_hash(hash_name);
243 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
244 rv = ecc_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
245 &self->yarrow_prng_state, self->yarrow_prng_index,
246 hash_id, &self->key);
247 if (rv != CRYPT_OK) croak("FATAL: ecc_encrypt_key failed: %s", error_to_string(rv));
248 RETVAL = newSVpvn((char*)buffer, buffer_len);
249 }
250 OUTPUT:
251 RETVAL
252
253 SV *
254 _decrypt(Crypt::PK::ECC self, SV * data)
255 CODE:
256 {
257 int rv;
258 unsigned char *data_ptr=NULL;
259 STRLEN data_len=0;
260 unsigned char buffer[1024];
261 unsigned long buffer_len = 1024;
262
263 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
264
265 rv = ecc_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
266 if (rv != CRYPT_OK) croak("FATAL: ecc_decrypt_key_ex failed: %s", error_to_string(rv));
267 RETVAL = newSVpvn((char*)buffer, buffer_len);
268 }
269 OUTPUT:
270 RETVAL
271
272 SV *
273 _sign(Crypt::PK::ECC self, SV * data)
274 ALIAS:
275 _sign_rfc7518 = 1
276 CODE:
277 {
278 int rv;
279 unsigned char *data_ptr=NULL;
280 STRLEN data_len=0;
281 unsigned char buffer[1024];
282 unsigned long buffer_len = 1024;
283
284 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
285
286 if (ix == 1) {
287 rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
288 &self->yarrow_prng_state, self->yarrow_prng_index,
289 &self->key);
290 }
291 else {
292 rv = ecc_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
293 &self->yarrow_prng_state, self->yarrow_prng_index,
294 &self->key);
295 }
296 if (rv != CRYPT_OK) croak("FATAL: ecc_sign_hash_ex failed: %s", error_to_string(rv));
297 RETVAL = newSVpvn((char*)buffer, buffer_len);
298 }
299 OUTPUT:
300 RETVAL
301
302 int
303 _verify(Crypt::PK::ECC self, SV * sig, SV * data)
304 ALIAS:
305 _verify_rfc7518 = 1
306 CODE:
307 {
308 int rv, stat;
309 unsigned char *data_ptr=NULL;
310 STRLEN data_len=0;
311 unsigned char *sig_ptr=NULL;
312 STRLEN sig_len=0;
313
314 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
315 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
316
317 RETVAL = 1;
318 if (ix == 1) {
319 rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
320 }
321 else {
322 rv = ecc_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
323 }
324 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
325 }
326 OUTPUT:
327 RETVAL
328
329 SV *
330 shared_secret(Crypt::PK::ECC self, Crypt::PK::ECC pubkey)
331 CODE:
332 {
333 int rv;
334 unsigned char buffer[1024];
335 unsigned long buffer_len = 1024;
336
337 rv = ecc_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
338 if (rv != CRYPT_OK) croak("FATAL: ecc_shared_secret failed: %s", error_to_string(rv));
339 RETVAL = newSVpvn((char*)buffer, buffer_len);
340 }
341 OUTPUT:
342 RETVAL
343
344 void
345 DESTROY(Crypt::PK::ECC self)
346 CODE:
347 _ecc_free_key(&self->key, &self->dp);
348 Safefree(self);
349
0 MODULE = CryptX PACKAGE = Crypt::PK::RSA
1
2 Crypt::PK::RSA
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct rsa_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::RSA self, int key_size=256, long key_e=65537)
20 PPCODE:
21 {
22 /* key_size is in octets */
23 int rv;
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* gen the key */
28 rv = rsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, key_e, &self->key);
29 if (rv != CRYPT_OK) croak("FATAL: rsa_make_key failed: %s", error_to_string(rv));
30 XPUSHs(ST(0)); /* return self */
31 }
32
33 void
34 _import(Crypt::PK::RSA self, SV * key_data)
35 PPCODE:
36 {
37 int rv;
38 unsigned char *data=NULL;
39 STRLEN data_len=0;
40
41 data = (unsigned char *)SvPVbyte(key_data, data_len);
42 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
43 rv = rsa_import(data, (unsigned long)data_len, &self->key);
44 if (rv != CRYPT_OK) croak("FATAL: rsa_import failed: %s", error_to_string(rv));
45 XPUSHs(ST(0)); /* return self */
46 }
47
48 void
49 _import_pkcs8(Crypt::PK::RSA self, SV * key_data)
50 PPCODE:
51 {
52 int rv;
53 unsigned char *data=NULL;
54 STRLEN data_len=0;
55
56 data = (unsigned char *)SvPVbyte(key_data, data_len);
57 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
58 rv = rsa_import_pkcs8(data, (unsigned long)data_len, &self->key);
59 if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv));
60 XPUSHs(ST(0)); /* return self */
61 }
62
63 void
64 _import_hex(Crypt::PK::RSA self, char *N, char *e, char *d=NULL, char *p=NULL, char *q=NULL, char *dP=NULL, char *dQ=NULL, char *qP=NULL)
65 PPCODE:
66 {
67 int rv;
68 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
69 rv = rsa_import_hex(N, e, d, p, q, dP, dQ, qP, &self->key);
70 if (rv != CRYPT_OK) croak("FATAL: rsa_import_hex failed: %s", error_to_string(rv));
71 XPUSHs(ST(0)); /* return self */
72 }
73
74 int
75 is_private(Crypt::PK::RSA self)
76 CODE:
77 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
78 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
79 OUTPUT:
80 RETVAL
81
82 int
83 size(Crypt::PK::RSA self)
84 CODE:
85 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
86 RETVAL = mp_unsigned_bin_size(self->key.N);
87 OUTPUT:
88 RETVAL
89
90 SV*
91 key2hash(Crypt::PK::RSA self)
92 PREINIT:
93 HV *rv_hash;
94 long siz;
95 char buf[20001];
96 SV **not_used;
97 CODE:
98 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
99 rv_hash = newHV();
100 /* =====> e */
101 siz = (self->key.e) ? mp_unsigned_bin_size(self->key.e) : 0;
102 if (siz>10000) {
103 croak("FATAL: key2hash failed - 'e' too big number");
104 }
105 if (siz>0) {
106 mp_tohex(self->key.e, buf);
107 not_used = hv_store(rv_hash, "e", 1, newSVpv(buf, strlen(buf)), 0);
108 }
109 else{
110 not_used = hv_store(rv_hash, "e", 1, newSVpv("", 0), 0);
111 }
112 /* =====> d */
113 siz = (self->key.d) ? mp_unsigned_bin_size(self->key.d) : 0;
114 if (siz>10000) {
115 croak("FATAL: key2hash failed - 'd' too big number");
116 }
117 if (siz>0) {
118 mp_tohex(self->key.d, buf);
119 not_used = hv_store(rv_hash, "d", 1, newSVpv(buf, strlen(buf)), 0);
120 }
121 else{
122 not_used = hv_store(rv_hash, "d", 1, newSVpv("", 0), 0);
123 }
124 /* =====> N */
125 siz = (self->key.N) ? mp_unsigned_bin_size(self->key.N) : 0;
126 if (siz>10000) {
127 croak("FATAL: key2hash failed - 'N' too big number");
128 }
129 if (siz>0) {
130 mp_tohex(self->key.N, buf);
131 not_used = hv_store(rv_hash, "N", 1, newSVpv(buf, strlen(buf)), 0);
132 }
133 else{
134 not_used = hv_store(rv_hash, "N", 1, newSVpv("", 0), 0);
135 }
136 /* =====> q */
137 siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0;
138 if (siz>10000) {
139 croak("FATAL: key2hash failed - 'q' too big number");
140 }
141 if (siz>0) {
142 mp_tohex(self->key.q, buf);
143 not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
144 }
145 else{
146 not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
147 }
148 /* =====> p */
149 siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0;
150 if (siz>10000) {
151 croak("FATAL: key2hash failed - 'p' too big number");
152 }
153 if (siz>0) {
154 mp_tohex(self->key.p, buf);
155 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
156 }
157 else{
158 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
159 }
160 /* =====> qP */
161 siz = (self->key.qP) ? mp_unsigned_bin_size(self->key.qP) : 0;
162 if (siz>10000) {
163 croak("FATAL: key2hash failed - 'qP' too big number");
164 }
165 if (siz>0) {
166 mp_tohex(self->key.qP, buf);
167 not_used = hv_store(rv_hash, "qP", 2, newSVpv(buf, strlen(buf)), 0);
168 }
169 else{
170 not_used = hv_store(rv_hash, "qP", 2, newSVpv("", 0), 0);
171 }
172 /* =====> dP */
173 siz = (self->key.dP) ? mp_unsigned_bin_size(self->key.dP) : 0;
174 if (siz>10000) {
175 croak("FATAL: key2hash failed - 'dP' too big number");
176 }
177 if (siz>0) {
178 mp_tohex(self->key.dP, buf);
179 not_used = hv_store(rv_hash, "dP", 2, newSVpv(buf, strlen(buf)), 0);
180 }
181 else{
182 not_used = hv_store(rv_hash, "dP", 2, newSVpv("", 0), 0);
183 }
184 /* =====> dQ */
185 siz = (self->key.dQ) ? mp_unsigned_bin_size(self->key.dQ) : 0;
186 if (siz>10000) {
187 croak("FATAL: key2hash failed - 'dQ' too big number");
188 }
189 if (siz>0) {
190 mp_tohex(self->key.dQ, buf);
191 not_used = hv_store(rv_hash, "dQ", 2, newSVpv(buf, strlen(buf)), 0);
192 }
193 else{
194 not_used = hv_store(rv_hash, "dQ", 2, newSVpv("", 0), 0);
195 }
196 /* =====> size */
197 not_used = hv_store(rv_hash, "size", 4, newSViv(mp_unsigned_bin_size(self->key.N)), 0);
198 /* =====> type */
199 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
200 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
201 RETVAL = newRV_noinc((SV*)rv_hash);
202 OUTPUT:
203 RETVAL
204
205 SV*
206 export_key_der(Crypt::PK::RSA self, char * type)
207 CODE:
208 {
209 int rv;
210 unsigned char out[4096];
211 unsigned long int out_len = 4096;
212
213 RETVAL = newSVpvn(NULL, 0); /* undef */
214 if (strnEQ(type, "private", 7)) {
215 rv = rsa_export(out, &out_len, PK_PRIVATE, &self->key);
216 if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PRIVATE) failed: %s", error_to_string(rv));
217 RETVAL = newSVpvn((char*)out, out_len);
218 }
219 else if (strnEQ(type, "public", 6)) {
220 rv = rsa_export(out, &out_len, PK_PUBLIC, &self->key);
221 if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PUBLIC) failed: %s", error_to_string(rv));
222 RETVAL = newSVpvn((char*)out, out_len);
223 }
224 else {
225 croak("FATAL: export_key_der invalid type '%s'", type);
226 }
227 }
228 OUTPUT:
229 RETVAL
230
231 SV *
232 _encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam)
233 CODE:
234 {
235 int rv, hash_id;
236 unsigned char *lparam_ptr=NULL;
237 STRLEN lparam_len=0;
238 unsigned char *data_ptr=NULL;
239 STRLEN data_len=0;
240 unsigned char buffer[1024];
241 unsigned long buffer_len = 1024;
242
243 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
244
245 RETVAL = newSVpvn(NULL, 0); /* undef */
246 if (strnEQ(padding, "oaep", 4)) {
247 hash_id = find_hash(oaep_hash);
248 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash);
249 lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len);
250 rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len,
251 &self->yarrow_prng_state, self->yarrow_prng_index,
252 hash_id, LTC_PKCS_1_OAEP, &self->key);
253 if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv));
254 RETVAL = newSVpvn((char*)buffer, buffer_len);
255 }
256 else if (strnEQ(padding, "v1.5", 4)) {
257 rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0,
258 &self->yarrow_prng_state, self->yarrow_prng_index,
259 0, LTC_PKCS_1_V1_5, &self->key);
260 if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv));
261 RETVAL = newSVpvn((char*)buffer, buffer_len);
262 }
263 else if (strnEQ(padding, "none", 4)) {
264 /* raw RSA */
265 rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PUBLIC, &self->key);
266 if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv));
267 RETVAL = newSVpvn((char*)buffer, buffer_len);
268 }
269 else {
270 croak("FATAL: rsa_encrypt invalid padding '%s'", padding);
271 }
272 }
273 OUTPUT:
274 RETVAL
275
276 SV *
277 _decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam)
278 CODE:
279 {
280 int rv, hash_id, stat;
281 unsigned char *lparam_ptr=NULL;
282 STRLEN lparam_len=0;
283 unsigned char *data_ptr=NULL;
284 STRLEN data_len=0;
285 unsigned char buffer[1024];
286 unsigned long buffer_len = 1024;
287
288 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
289
290 RETVAL = newSVpvn(NULL, 0); /* undef */
291 if (strnEQ(padding, "oaep", 4)) {
292 hash_id = find_hash(oaep_hash);
293 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash);
294 lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len);
295 rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len,
296 hash_id, LTC_PKCS_1_OAEP, &stat, &self->key);
297 if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv));
298 if (stat != 1) croak("FATAL: rsa_decrypt - not valid OAEP packet");
299 RETVAL = newSVpvn((char*)buffer, buffer_len);
300 }
301 else if (strnEQ(padding, "v1.5", 4)) {
302 rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0,
303 0, LTC_PKCS_1_V1_5, &stat, &self->key);
304 if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv));
305 if (stat != 1) croak("FATAL: rsa_decrypt - invalid");
306 RETVAL = newSVpvn((char*)buffer, buffer_len);
307 }
308 else if (strnEQ(padding, "none", 4)) {
309 /* raw RSA */
310 rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PRIVATE, &self->key);
311 if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv));
312 RETVAL = newSVpvn((char*)buffer, buffer_len);
313 }
314 else {
315 croak("FATAL: rsa_encrypt invalid padding '%s'", padding);
316 }
317 }
318 OUTPUT:
319 RETVAL
320
321 SV *
322 _sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name, unsigned long saltlen=12)
323 CODE:
324 {
325 int rv, hash_id;
326 unsigned char *data_ptr=NULL;
327 STRLEN data_len=0;
328 unsigned char buffer[1024];
329 unsigned long buffer_len = 1024;
330
331 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
332
333 RETVAL = newSVpvn(NULL, 0); /* undef */
334 hash_id = find_hash(hash_name);
335 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
336 if (strnEQ(padding, "pss", 3)) {
337 rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_PSS,
338 &self->yarrow_prng_state, self->yarrow_prng_index,
339 hash_id, saltlen, &self->key);
340 if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv));
341 RETVAL = newSVpvn((char*)buffer, buffer_len);
342 }
343 else if (strnEQ(padding, "v1.5", 4)) {
344 rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_V1_5,
345 &self->yarrow_prng_state, self->yarrow_prng_index,
346 hash_id, 0, &self->key);
347 if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv));
348 RETVAL = newSVpvn((char*)buffer, buffer_len);
349 }
350 else {
351 croak("FATAL: rsa_sign invalid padding '%s'", padding);
352 }
353 }
354 OUTPUT:
355 RETVAL
356
357 int
358 _verify(Crypt::PK::RSA self, SV * sig, SV * data, char * padding, char * hash_name, unsigned long saltlen=12)
359 CODE:
360 {
361 int rv, hash_id, stat;
362 unsigned char *data_ptr=NULL;
363 STRLEN data_len=0;
364 unsigned char *sig_ptr=NULL;
365 STRLEN sig_len=0;
366
367 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
368 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
369
370 RETVAL = 1;
371 hash_id = find_hash(hash_name);
372 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
373 if (strnEQ(padding, "pss", 3)) {
374 rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_PSS,
375 hash_id, saltlen, &stat, &self->key);
376 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
377 }
378 else if (strnEQ(padding, "v1.5", 4)) {
379 rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_V1_5,
380 hash_id, 0, &stat, &self->key);
381 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
382 }
383 else {
384 croak("FATAL: rsa_verify invalid padding '%s'", padding);
385 }
386 }
387 OUTPUT:
388 RETVAL
389
390 void
391 DESTROY(Crypt::PK::RSA self)
392 CODE:
393 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
394 Safefree(self);
395
0 MODULE = CryptX PACKAGE = Crypt::PK::RSA
1
2 Crypt::PK::RSA
3 _new()
4 CODE:
5 {
6 int rv;
7 Newz(0, RETVAL, 1, struct rsa_struct);
8 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
14 }
15 OUTPUT:
16 RETVAL
17
18 void
19 generate_key(Crypt::PK::RSA self, int key_size=256, long key_e=65537)
20 PPCODE:
21 {
22 /* key_size is in octets */
23 int rv;
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* gen the key */
28 rv = rsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, key_e, &self->key);
29 if (rv != CRYPT_OK) croak("FATAL: rsa_make_key failed: %s", error_to_string(rv));
30 XPUSHs(ST(0)); /* return self */
31 }
32
33 void
34 _import(Crypt::PK::RSA self, SV * key_data)
35 PPCODE:
36 {
37 int rv;
38 unsigned char *data=NULL;
39 STRLEN data_len=0;
40
41 data = (unsigned char *)SvPVbyte(key_data, data_len);
42 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
43 rv = rsa_import(data, (unsigned long)data_len, &self->key);
44 if (rv != CRYPT_OK) croak("FATAL: rsa_import failed: %s", error_to_string(rv));
45 XPUSHs(ST(0)); /* return self */
46 }
47
48 void
49 _import_pkcs8(Crypt::PK::RSA self, SV * key_data)
50 PPCODE:
51 {
52 int rv;
53 unsigned char *data=NULL;
54 STRLEN data_len=0;
55
56 data = (unsigned char *)SvPVbyte(key_data, data_len);
57 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
58 rv = rsa_import_pkcs8(data, (unsigned long)data_len, &self->key);
59 if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv));
60 XPUSHs(ST(0)); /* return self */
61 }
62
63 void
64 _import_hex(Crypt::PK::RSA self, char *N, char *e, char *d=NULL, char *p=NULL, char *q=NULL, char *dP=NULL, char *dQ=NULL, char *qP=NULL)
65 PPCODE:
66 {
67 int rv;
68 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
69 rv = rsa_import_hex(N, e, d, p, q, dP, dQ, qP, &self->key);
70 if (rv != CRYPT_OK) croak("FATAL: rsa_import_hex failed: %s", error_to_string(rv));
71 XPUSHs(ST(0)); /* return self */
72 }
73
74 int
75 is_private(Crypt::PK::RSA self)
76 CODE:
77 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
78 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
79 OUTPUT:
80 RETVAL
81
82 int
83 size(Crypt::PK::RSA self)
84 CODE:
85 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
86 RETVAL = mp_unsigned_bin_size(self->key.N);
87 OUTPUT:
88 RETVAL
89
90 SV*
91 key2hash(Crypt::PK::RSA self)
92 PREINIT:
93 HV *rv_hash;
94 long siz;
95 char buf[20001];
96 SV **not_used;
97 CODE:
98 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
99 rv_hash = newHV();
100 /* =====> e */
101 siz = (self->key.e) ? mp_unsigned_bin_size(self->key.e) : 0;
102 if (siz>10000) {
103 croak("FATAL: key2hash failed - 'e' too big number");
104 }
105 if (siz>0) {
106 mp_tohex(self->key.e, buf);
107 not_used = hv_store(rv_hash, "e", 1, newSVpv(buf, strlen(buf)), 0);
108 }
109 else{
110 not_used = hv_store(rv_hash, "e", 1, newSVpv("", 0), 0);
111 }
112 /* =====> d */
113 siz = (self->key.d) ? mp_unsigned_bin_size(self->key.d) : 0;
114 if (siz>10000) {
115 croak("FATAL: key2hash failed - 'd' too big number");
116 }
117 if (siz>0) {
118 mp_tohex(self->key.d, buf);
119 not_used = hv_store(rv_hash, "d", 1, newSVpv(buf, strlen(buf)), 0);
120 }
121 else{
122 not_used = hv_store(rv_hash, "d", 1, newSVpv("", 0), 0);
123 }
124 /* =====> N */
125 siz = (self->key.N) ? mp_unsigned_bin_size(self->key.N) : 0;
126 if (siz>10000) {
127 croak("FATAL: key2hash failed - 'N' too big number");
128 }
129 if (siz>0) {
130 mp_tohex(self->key.N, buf);
131 not_used = hv_store(rv_hash, "N", 1, newSVpv(buf, strlen(buf)), 0);
132 }
133 else{
134 not_used = hv_store(rv_hash, "N", 1, newSVpv("", 0), 0);
135 }
136 /* =====> q */
137 siz = (self->key.q) ? mp_unsigned_bin_size(self->key.q) : 0;
138 if (siz>10000) {
139 croak("FATAL: key2hash failed - 'q' too big number");
140 }
141 if (siz>0) {
142 mp_tohex(self->key.q, buf);
143 not_used = hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
144 }
145 else{
146 not_used = hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
147 }
148 /* =====> p */
149 siz = (self->key.p) ? mp_unsigned_bin_size(self->key.p) : 0;
150 if (siz>10000) {
151 croak("FATAL: key2hash failed - 'p' too big number");
152 }
153 if (siz>0) {
154 mp_tohex(self->key.p, buf);
155 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
156 }
157 else{
158 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
159 }
160 /* =====> qP */
161 siz = (self->key.qP) ? mp_unsigned_bin_size(self->key.qP) : 0;
162 if (siz>10000) {
163 croak("FATAL: key2hash failed - 'qP' too big number");
164 }
165 if (siz>0) {
166 mp_tohex(self->key.qP, buf);
167 not_used = hv_store(rv_hash, "qP", 2, newSVpv(buf, strlen(buf)), 0);
168 }
169 else{
170 not_used = hv_store(rv_hash, "qP", 2, newSVpv("", 0), 0);
171 }
172 /* =====> dP */
173 siz = (self->key.dP) ? mp_unsigned_bin_size(self->key.dP) : 0;
174 if (siz>10000) {
175 croak("FATAL: key2hash failed - 'dP' too big number");
176 }
177 if (siz>0) {
178 mp_tohex(self->key.dP, buf);
179 not_used = hv_store(rv_hash, "dP", 2, newSVpv(buf, strlen(buf)), 0);
180 }
181 else{
182 not_used = hv_store(rv_hash, "dP", 2, newSVpv("", 0), 0);
183 }
184 /* =====> dQ */
185 siz = (self->key.dQ) ? mp_unsigned_bin_size(self->key.dQ) : 0;
186 if (siz>10000) {
187 croak("FATAL: key2hash failed - 'dQ' too big number");
188 }
189 if (siz>0) {
190 mp_tohex(self->key.dQ, buf);
191 not_used = hv_store(rv_hash, "dQ", 2, newSVpv(buf, strlen(buf)), 0);
192 }
193 else{
194 not_used = hv_store(rv_hash, "dQ", 2, newSVpv("", 0), 0);
195 }
196 /* =====> size */
197 not_used = hv_store(rv_hash, "size", 4, newSViv(mp_unsigned_bin_size(self->key.N)), 0);
198 /* =====> type */
199 not_used = hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
200 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
201 RETVAL = newRV_noinc((SV*)rv_hash);
202 OUTPUT:
203 RETVAL
204
205 SV*
206 export_key_der(Crypt::PK::RSA self, char * type)
207 CODE:
208 {
209 int rv;
210 unsigned char out[4096];
211 unsigned long int out_len = 4096;
212
213 RETVAL = newSVpvn(NULL, 0); /* undef */
214 if (strnEQ(type, "private", 7)) {
215 rv = rsa_export(out, &out_len, PK_PRIVATE, &self->key);
216 if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PRIVATE) failed: %s", error_to_string(rv));
217 RETVAL = newSVpvn((char*)out, out_len);
218 }
219 else if (strnEQ(type, "public", 6)) {
220 rv = rsa_export(out, &out_len, PK_PUBLIC, &self->key);
221 if (rv != CRYPT_OK) croak("FATAL: rsa_export(PK_PUBLIC) failed: %s", error_to_string(rv));
222 RETVAL = newSVpvn((char*)out, out_len);
223 }
224 else {
225 croak("FATAL: export_key_der invalid type '%s'", type);
226 }
227 }
228 OUTPUT:
229 RETVAL
230
231 SV *
232 _encrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam)
233 CODE:
234 {
235 int rv, hash_id;
236 unsigned char *lparam_ptr=NULL;
237 STRLEN lparam_len=0;
238 unsigned char *data_ptr=NULL;
239 STRLEN data_len=0;
240 unsigned char buffer[1024];
241 unsigned long buffer_len = 1024;
242
243 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
244
245 RETVAL = newSVpvn(NULL, 0); /* undef */
246 if (strnEQ(padding, "oaep", 4)) {
247 hash_id = find_hash(oaep_hash);
248 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash);
249 lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len);
250 rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len,
251 &self->yarrow_prng_state, self->yarrow_prng_index,
252 hash_id, LTC_PKCS_1_OAEP, &self->key);
253 if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv));
254 RETVAL = newSVpvn((char*)buffer, buffer_len);
255 }
256 else if (strnEQ(padding, "v1.5", 4)) {
257 rv = rsa_encrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0,
258 &self->yarrow_prng_state, self->yarrow_prng_index,
259 0, LTC_PKCS_1_V1_5, &self->key);
260 if (rv != CRYPT_OK) croak("FATAL: rsa_encrypt_key_ex failed: %s", error_to_string(rv));
261 RETVAL = newSVpvn((char*)buffer, buffer_len);
262 }
263 else if (strnEQ(padding, "none", 4)) {
264 /* raw RSA */
265 rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PUBLIC, &self->key);
266 if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv));
267 RETVAL = newSVpvn((char*)buffer, buffer_len);
268 }
269 else {
270 croak("FATAL: rsa_encrypt invalid padding '%s'", padding);
271 }
272 }
273 OUTPUT:
274 RETVAL
275
276 SV *
277 _decrypt(Crypt::PK::RSA self, SV * data, char * padding, char * oaep_hash, SV * oaep_lparam)
278 CODE:
279 {
280 int rv, hash_id, stat;
281 unsigned char *lparam_ptr=NULL;
282 STRLEN lparam_len=0;
283 unsigned char *data_ptr=NULL;
284 STRLEN data_len=0;
285 unsigned char buffer[1024];
286 unsigned long buffer_len = 1024;
287
288 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
289
290 RETVAL = newSVpvn(NULL, 0); /* undef */
291 if (strnEQ(padding, "oaep", 4)) {
292 hash_id = find_hash(oaep_hash);
293 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", oaep_hash);
294 lparam_ptr = (unsigned char *)SvPVbyte(oaep_lparam, lparam_len);
295 rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, lparam_ptr, (unsigned long)lparam_len,
296 hash_id, LTC_PKCS_1_OAEP, &stat, &self->key);
297 if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv));
298 if (stat != 1) croak("FATAL: rsa_decrypt - not valid OAEP packet");
299 RETVAL = newSVpvn((char*)buffer, buffer_len);
300 }
301 else if (strnEQ(padding, "v1.5", 4)) {
302 rv = rsa_decrypt_key_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, NULL, 0,
303 0, LTC_PKCS_1_V1_5, &stat, &self->key);
304 if (rv != CRYPT_OK) croak("FATAL: rsa_decrypt_key_ex failed: %s", error_to_string(rv));
305 if (stat != 1) croak("FATAL: rsa_decrypt - invalid");
306 RETVAL = newSVpvn((char*)buffer, buffer_len);
307 }
308 else if (strnEQ(padding, "none", 4)) {
309 /* raw RSA */
310 rv = ltc_mp.rsa_me(data_ptr, (unsigned long)data_len, buffer, &buffer_len, PK_PRIVATE, &self->key);
311 if (rv != CRYPT_OK) croak("FATAL: rsa_me failed: %s", error_to_string(rv));
312 RETVAL = newSVpvn((char*)buffer, buffer_len);
313 }
314 else {
315 croak("FATAL: rsa_encrypt invalid padding '%s'", padding);
316 }
317 }
318 OUTPUT:
319 RETVAL
320
321 SV *
322 _sign(Crypt::PK::RSA self, SV * data, char * padding, char * hash_name, unsigned long saltlen=12)
323 CODE:
324 {
325 int rv, hash_id;
326 unsigned char *data_ptr=NULL;
327 STRLEN data_len=0;
328 unsigned char buffer[1024];
329 unsigned long buffer_len = 1024;
330
331 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
332
333 RETVAL = newSVpvn(NULL, 0); /* undef */
334 hash_id = find_hash(hash_name);
335 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
336 if (strnEQ(padding, "pss", 3)) {
337 rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_PSS,
338 &self->yarrow_prng_state, self->yarrow_prng_index,
339 hash_id, saltlen, &self->key);
340 if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv));
341 RETVAL = newSVpvn((char*)buffer, buffer_len);
342 }
343 else if (strnEQ(padding, "v1.5", 4)) {
344 rv = rsa_sign_hash_ex(data_ptr, (unsigned long)data_len, buffer, &buffer_len, LTC_PKCS_1_V1_5,
345 &self->yarrow_prng_state, self->yarrow_prng_index,
346 hash_id, 0, &self->key);
347 if (rv != CRYPT_OK) croak("FATAL: rsa_sign_hash_ex failed: %s", error_to_string(rv));
348 RETVAL = newSVpvn((char*)buffer, buffer_len);
349 }
350 else {
351 croak("FATAL: rsa_sign invalid padding '%s'", padding);
352 }
353 }
354 OUTPUT:
355 RETVAL
356
357 int
358 _verify(Crypt::PK::RSA self, SV * sig, SV * data, char * padding, char * hash_name, unsigned long saltlen=12)
359 CODE:
360 {
361 int rv, hash_id, stat;
362 unsigned char *data_ptr=NULL;
363 STRLEN data_len=0;
364 unsigned char *sig_ptr=NULL;
365 STRLEN sig_len=0;
366
367 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
368 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
369
370 RETVAL = 1;
371 hash_id = find_hash(hash_name);
372 if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name);
373 if (strnEQ(padding, "pss", 3)) {
374 rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_PSS,
375 hash_id, saltlen, &stat, &self->key);
376 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
377 }
378 else if (strnEQ(padding, "v1.5", 4)) {
379 rv = rsa_verify_hash_ex(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, LTC_PKCS_1_V1_5,
380 hash_id, 0, &stat, &self->key);
381 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
382 }
383 else {
384 croak("FATAL: rsa_verify invalid padding '%s'", padding);
385 }
386 }
387 OUTPUT:
388 RETVAL
389
390 void
391 DESTROY(Crypt::PK::RSA self)
392 CODE:
393 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
394 Safefree(self);
395
0 MODULE = CryptX PACKAGE = Crypt::PRNG
1
2 Crypt::PRNG
3 _new(IV curpid, char * prng_name, SV * entropy=&PL_sv_undef)
4 CODE:
5 {
6 int rv, id;
7 unsigned char *ent=NULL;
8 STRLEN ent_len=0;
9 unsigned char entropy_buf[32];
10
11 Newz(0, RETVAL, 1, struct prng_struct);
12 if (!RETVAL) croak("FATAL: Newz failed");
13
14 id = find_prng(prng_name);
15 if(id==-1) croak("FATAL: find_prng failed for '%s'", prng_name);
16 RETVAL->id = id;
17 RETVAL->last_pid = curpid;
18 RETVAL->desc = &prng_descriptor[id];
19
20 rv = RETVAL->desc->start(&RETVAL->state);
21 if (rv != CRYPT_OK) croak("FATAL: PRNG_start failed: %s", error_to_string(rv));
22
23 if(SvOK(entropy)) {
24 ent = (unsigned char *) SvPVbyte(entropy, ent_len);
25 rv = RETVAL->desc->add_entropy(ent, (unsigned long)ent_len, &RETVAL->state);
26 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
27 }
28 else {
29 if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed: %s", error_to_string(rv));
30 rv = RETVAL->desc->add_entropy(entropy_buf, 32, &RETVAL->state);
31 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
32 }
33 rv = RETVAL->desc->ready(&RETVAL->state);
34 if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
35 }
36 OUTPUT:
37 RETVAL
38
39 void
40 DESTROY(Crypt::PRNG self)
41 CODE:
42 {
43 Safefree(self);
44 }
45
46 void
47 add_entropy(Crypt::PRNG self, SV * entropy=&PL_sv_undef)
48 CODE:
49 {
50 STRLEN in_len=0;
51 unsigned char *in_buffer=NULL;
52 unsigned char entropy_buf[32];
53 int rv;
54 if(SvOK(entropy)) {
55 in_buffer = (unsigned char *) SvPVbyte(entropy, in_len);
56 rv = self->desc->add_entropy(in_buffer, (unsigned long)in_len, &self->state);
57 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
58 }
59 else {
60 if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed");
61 rv = self->desc->add_entropy(entropy_buf, 32, &self->state);
62 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
63 }
64 rv = self->desc->ready(&self->state);
65 if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
66 }
67
68 SV *
69 _bytes(Crypt::PRNG self, IV curpid, STRLEN output_len)
70 CODE:
71 {
72 int rv_len;
73 unsigned char *rdata;
74 unsigned char entropy_buf[32];
75
76 if (self->last_pid != curpid) {
77 rng_get_bytes(entropy_buf, 32, NULL);
78 self->desc->add_entropy(entropy_buf, 32, &self->state);
79 self->desc->ready(&self->state);
80 self->last_pid = curpid;
81 }
82
83 RETVAL = NEWSV(0, output_len);
84 SvPOK_only(RETVAL);
85 SvCUR_set(RETVAL, output_len);
86 rdata = (unsigned char *)SvPV_nolen(RETVAL);
87 rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state);
88 if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed");
89 }
90 OUTPUT:
91 RETVAL
92
93 UV
94 _int32(Crypt::PRNG self, IV curpid)
95 CODE:
96 {
97 int i;
98 unsigned char rdata[4];
99 unsigned char entropy_buf[32];
100
101 if (self->last_pid != curpid) {
102 rng_get_bytes(entropy_buf, 32, NULL);
103 self->desc->add_entropy(entropy_buf, 32, &self->state);
104 self->desc->ready(&self->state);
105 self->last_pid = curpid;
106 }
107
108 i = (self->desc->read)(rdata, 4, &self->state);
109 if (i != 4) croak("FATAL: PRNG_read failed");
110 RETVAL = ((UV)(rdata[0])<<24) + ((UV)(rdata[1])<<16) + ((UV)(rdata[2])<<8) + ((UV)(rdata[3]));
111 }
112 OUTPUT:
113 RETVAL
114
115 NV
116 _double(Crypt::PRNG self, IV curpid, ...)
117 CODE:
118 {
119 int i;
120 unsigned long a, b; /* 32bit is enough */
121 unsigned char rdata[7]; /* for double we need 53 bits */
122 unsigned char entropy_buf[32];
123 NV limit;
124
125 if (self->last_pid != curpid) {
126 rng_get_bytes(entropy_buf, 32, NULL);
127 self->desc->add_entropy(entropy_buf, 32, &self->state);
128 self->desc->ready(&self->state);
129 self->last_pid = curpid;
130 }
131
132 i = (self->desc->read)(rdata, 7, &self->state);
133 if (i != 7) croak("FATAL: PRNG_read failed");
134 a = (((unsigned long)(rdata[0])<<16) + ((unsigned long)(rdata[1])<<8) + ((unsigned long)(rdata[2]))) & 0x1FFFFF; /* 21 bits */
135 b = ((unsigned long)(rdata[3])<<24) + ((unsigned long)(rdata[4])<<16) + ((unsigned long)(rdata[5])<<8) + ((unsigned long)(rdata[6])); /* 32 bits */
136 RETVAL = ( (NV)a * 4294967296.0 + (NV)b ) / 9007199254740992.0; /* (a * 2^32 + b) / 2^53 */
137 if (items>2 && SvOK(ST(2))) {
138 limit = SvNV(ST(2));
139 if (limit > 0 || limit < 0) RETVAL = RETVAL * limit;
140 }
141 }
142 OUTPUT:
143 RETVAL
0 MODULE = CryptX PACKAGE = Crypt::PRNG
1
2 Crypt::PRNG
3 _new(IV curpid, char * prng_name, SV * entropy=&PL_sv_undef)
4 CODE:
5 {
6 int rv, id;
7 unsigned char *ent=NULL;
8 STRLEN ent_len=0;
9 unsigned char entropy_buf[32];
10
11 Newz(0, RETVAL, 1, struct prng_struct);
12 if (!RETVAL) croak("FATAL: Newz failed");
13
14 id = find_prng(prng_name);
15 if(id==-1) croak("FATAL: find_prng failed for '%s'", prng_name);
16 RETVAL->id = id;
17 RETVAL->last_pid = curpid;
18 RETVAL->desc = &prng_descriptor[id];
19
20 rv = RETVAL->desc->start(&RETVAL->state);
21 if (rv != CRYPT_OK) croak("FATAL: PRNG_start failed: %s", error_to_string(rv));
22
23 if(SvOK(entropy)) {
24 ent = (unsigned char *) SvPVbyte(entropy, ent_len);
25 rv = RETVAL->desc->add_entropy(ent, (unsigned long)ent_len, &RETVAL->state);
26 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
27 }
28 else {
29 if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed: %s", error_to_string(rv));
30 rv = RETVAL->desc->add_entropy(entropy_buf, 32, &RETVAL->state);
31 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
32 }
33 rv = RETVAL->desc->ready(&RETVAL->state);
34 if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
35 }
36 OUTPUT:
37 RETVAL
38
39 void
40 DESTROY(Crypt::PRNG self)
41 CODE:
42 {
43 Safefree(self);
44 }
45
46 void
47 add_entropy(Crypt::PRNG self, SV * entropy=&PL_sv_undef)
48 CODE:
49 {
50 STRLEN in_len=0;
51 unsigned char *in_buffer=NULL;
52 unsigned char entropy_buf[32];
53 int rv;
54 if(SvOK(entropy)) {
55 in_buffer = (unsigned char *) SvPVbyte(entropy, in_len);
56 rv = self->desc->add_entropy(in_buffer, (unsigned long)in_len, &self->state);
57 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
58 }
59 else {
60 if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed");
61 rv = self->desc->add_entropy(entropy_buf, 32, &self->state);
62 if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv));
63 }
64 rv = self->desc->ready(&self->state);
65 if (rv != CRYPT_OK) croak("FATAL: PRNG_ready failed: %s", error_to_string(rv));
66 }
67
68 SV *
69 _bytes(Crypt::PRNG self, IV curpid, STRLEN output_len)
70 CODE:
71 {
72 int rv_len;
73 unsigned char *rdata;
74 unsigned char entropy_buf[32];
75
76 if (self->last_pid != curpid) {
77 rng_get_bytes(entropy_buf, 32, NULL);
78 self->desc->add_entropy(entropy_buf, 32, &self->state);
79 self->desc->ready(&self->state);
80 self->last_pid = curpid;
81 }
82
83 RETVAL = NEWSV(0, output_len);
84 SvPOK_only(RETVAL);
85 SvCUR_set(RETVAL, output_len);
86 rdata = (unsigned char *)SvPV_nolen(RETVAL);
87 rv_len = (self->desc->read)(rdata, (unsigned long)output_len, &self->state);
88 if ((UV)rv_len != output_len) croak("FATAL: PRNG_read failed");
89 }
90 OUTPUT:
91 RETVAL
92
93 UV
94 _int32(Crypt::PRNG self, IV curpid)
95 CODE:
96 {
97 int i;
98 unsigned char rdata[4];
99 unsigned char entropy_buf[32];
100
101 if (self->last_pid != curpid) {
102 rng_get_bytes(entropy_buf, 32, NULL);
103 self->desc->add_entropy(entropy_buf, 32, &self->state);
104 self->desc->ready(&self->state);
105 self->last_pid = curpid;
106 }
107
108 i = (self->desc->read)(rdata, 4, &self->state);
109 if (i != 4) croak("FATAL: PRNG_read failed");
110 RETVAL = ((UV)(rdata[0])<<24) + ((UV)(rdata[1])<<16) + ((UV)(rdata[2])<<8) + ((UV)(rdata[3]));
111 }
112 OUTPUT:
113 RETVAL
114
115 NV
116 _double(Crypt::PRNG self, IV curpid, ...)
117 CODE:
118 {
119 int i;
120 unsigned long a, b; /* 32bit is enough */
121 unsigned char rdata[7]; /* for double we need 53 bits */
122 unsigned char entropy_buf[32];
123 NV limit;
124
125 if (self->last_pid != curpid) {
126 rng_get_bytes(entropy_buf, 32, NULL);
127 self->desc->add_entropy(entropy_buf, 32, &self->state);
128 self->desc->ready(&self->state);
129 self->last_pid = curpid;
130 }
131
132 i = (self->desc->read)(rdata, 7, &self->state);
133 if (i != 7) croak("FATAL: PRNG_read failed");
134 a = (((unsigned long)(rdata[0])<<16) + ((unsigned long)(rdata[1])<<8) + ((unsigned long)(rdata[2]))) & 0x1FFFFF; /* 21 bits */
135 b = ((unsigned long)(rdata[3])<<24) + ((unsigned long)(rdata[4])<<16) + ((unsigned long)(rdata[5])<<8) + ((unsigned long)(rdata[6])); /* 32 bits */
136 RETVAL = ( (NV)a * 4294967296.0 + (NV)b ) / 9007199254740992.0; /* (a * 2^32 + b) / 2^53 */
137 if (items>2 && SvOK(ST(2))) {
138 limit = SvNV(ST(2));
139 if (limit > 0 || limit < 0) RETVAL = RETVAL * limit;
140 }
141 }
142 OUTPUT:
143 RETVAL
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
3 "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
4 "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE",
5 "use":"enc",
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
3 "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
4 "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE",
5 "use":"enc",
66 "kid":"1"}
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
3 "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
4 "kid":"Public key used in JWS A.3 example"
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
3 "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
4 "kid":"Public key used in JWS A.3 example"
55 }
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
3 "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
4 "use":"enc",
0 {"kty":"EC",
1 "crv":"P-256",
2 "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
3 "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
4 "use":"enc",
55 "kid":"1"}
0 {
1 "kty":"RSA",
2 "kid":"juliet@capulet.lit",
3 "use":"enc",
4 "n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRyO125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0XOC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q",
5 "e":"AQAB",
6 "d":"GRtbIQmhOZtyszfgKdg4u_N-R_mZGU_9k7JQ_jn1DnfTuMdSNprTeaSTyWfSNkuaAwnOEbIQVy1IQbWVV25NY3ybc_IhUJtfri7bAXYEReWaCl3hdlPKXy9UvqPYGR0kIXTQRqns-dVJ7jahlI7LyckrpTmrM8dWBo4_PMaenNnPiQgO0xnuToxutRZJfJvG4Ox4ka3GORQd9CsCZ2vsUDmsXOfUENOyMqADC6p1M3h33tsurY15k9qMSpG9OX_IJAXmxzAh_tWiZOwk2K4yxH9tS3Lq1yX8C1EWmeRDkK2ahecG85-oLKQt5VEpWHKmjOi_gJSdSgqcN96X52esAQ",
7 "p":"2rnSOV4hKSN8sS4CgcQHFbs08XboFDqKum3sc4h3GRxrTmQdl1ZK9uw-PIHfQP0FkxXVrx-WE-ZEbrqivH_2iCLUS7wAl6XvARt1KkIaUxPPSYB9yk31s0Q8UK96E3_OrADAYtAJs-M3JxCLfNgqh56HDnETTQhH3rCT5T3yJws",
8 "q":"1u_RiFDP7LBYh3N4GXLT9OpSKYP0uQZyiaZwBtOCBNJgQxaj10RWjsZu0c6Iedis4S7B_coSKB0Kj9PaPaBzg-IySRvvcQuPamQu66riMhjVtG6TlV8CLCYKrYl52ziqK0E_ym2QnkwsUX7eYTB7LbAHRK9GqocDE5B0f808I4s",
9 "dp":"KkMTWqBUefVwZ2_Dbj1pPQqyHSHjj90L5x_MOzqYAJMcLMZtbUtwKqvVDq3tbEo3ZIcohbDtt6SbfmWzggabpQxNxuBpoOOf_a_HgMXK_lhqigI4y_kqS1wY52IwjUn5rgRrJ-yYo1h41KR-vz2pYhEAeYrhttWtxVqLCRViD6c",
10 "dq":"AvfS0-gRxvn0bwJoMSnFxYcK1WnuEjQFluMGfwGitQBWtfZ1Er7t1xDkbN9GQTB9yqpDoYaN06H7CFtrkxhJIBQaj6nkF5KKS3TQtQ5qCzkOkmxIe3KRbBymXxkb5qwUpX5ELD5xFc6FeiafWYY63TmmEAu_lRFCOJ3xDea-ots",
11 "qi":"lSQi-w9CpyUReMErP1RsBLk7wNtOvs5EQpPqmuMvqW57NBUczScEoPwmUqqabu9V0-Py4dQ57_bapoKRu1R90bvuFnU63SHWEFglZQvJDMeAvmj4sm-Fp0oYu_neotgQ0hzbI5gry7ajdYy9-2lNx_76aBZoOUu9HCJ-UsfSOI8"
0 {
1 "kty":"RSA",
2 "kid":"juliet@capulet.lit",
3 "use":"enc",
4 "n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRyO125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0XOC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q",
5 "e":"AQAB",
6 "d":"GRtbIQmhOZtyszfgKdg4u_N-R_mZGU_9k7JQ_jn1DnfTuMdSNprTeaSTyWfSNkuaAwnOEbIQVy1IQbWVV25NY3ybc_IhUJtfri7bAXYEReWaCl3hdlPKXy9UvqPYGR0kIXTQRqns-dVJ7jahlI7LyckrpTmrM8dWBo4_PMaenNnPiQgO0xnuToxutRZJfJvG4Ox4ka3GORQd9CsCZ2vsUDmsXOfUENOyMqADC6p1M3h33tsurY15k9qMSpG9OX_IJAXmxzAh_tWiZOwk2K4yxH9tS3Lq1yX8C1EWmeRDkK2ahecG85-oLKQt5VEpWHKmjOi_gJSdSgqcN96X52esAQ",
7 "p":"2rnSOV4hKSN8sS4CgcQHFbs08XboFDqKum3sc4h3GRxrTmQdl1ZK9uw-PIHfQP0FkxXVrx-WE-ZEbrqivH_2iCLUS7wAl6XvARt1KkIaUxPPSYB9yk31s0Q8UK96E3_OrADAYtAJs-M3JxCLfNgqh56HDnETTQhH3rCT5T3yJws",
8 "q":"1u_RiFDP7LBYh3N4GXLT9OpSKYP0uQZyiaZwBtOCBNJgQxaj10RWjsZu0c6Iedis4S7B_coSKB0Kj9PaPaBzg-IySRvvcQuPamQu66riMhjVtG6TlV8CLCYKrYl52ziqK0E_ym2QnkwsUX7eYTB7LbAHRK9GqocDE5B0f808I4s",
9 "dp":"KkMTWqBUefVwZ2_Dbj1pPQqyHSHjj90L5x_MOzqYAJMcLMZtbUtwKqvVDq3tbEo3ZIcohbDtt6SbfmWzggabpQxNxuBpoOOf_a_HgMXK_lhqigI4y_kqS1wY52IwjUn5rgRrJ-yYo1h41KR-vz2pYhEAeYrhttWtxVqLCRViD6c",
10 "dq":"AvfS0-gRxvn0bwJoMSnFxYcK1WnuEjQFluMGfwGitQBWtfZ1Er7t1xDkbN9GQTB9yqpDoYaN06H7CFtrkxhJIBQaj6nkF5KKS3TQtQ5qCzkOkmxIe3KRbBymXxkb5qwUpX5ELD5xFc6FeiafWYY63TmmEAu_lRFCOJ3xDea-ots",
11 "qi":"lSQi-w9CpyUReMErP1RsBLk7wNtOvs5EQpPqmuMvqW57NBUczScEoPwmUqqabu9V0-Py4dQ57_bapoKRu1R90bvuFnU63SHWEFglZQvJDMeAvmj4sm-Fp0oYu_neotgQ0hzbI5gry7ajdYy9-2lNx_76aBZoOUu9HCJ-UsfSOI8"
1212 }
0 {"kty":"RSA",
1 "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
2 "e":"AQAB",
3 "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
4 "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
5 "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
6 "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
7 "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
8 "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
9 "alg":"RS256",
0 {"kty":"RSA",
1 "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
2 "e":"AQAB",
3 "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
4 "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
5 "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
6 "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
7 "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
8 "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
9 "alg":"RS256",
1010 "kid":"2011-04-29"}
0 {"kty":"RSA",
1 "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
2 "e":"AQAB",
3 "alg":"RS256",
0 {"kty":"RSA",
1 "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
2 "e":"AQAB",
3 "alg":"RS256",
44 "kid":"2011-04-29"}