strip trailing spaces
Karel Miko
10 years ago
52 | 52 | #### send ($ciphertext, $tag, $nonce, $header) to other party |
53 | 53 | |
54 | 54 | my $plaintext = ccm_decrypt_verify('AES', $key, $nonce, $header, $ciphertext, $tag); |
55 | ||
55 | ||
56 | 56 | =head1 DESCRIPTION |
57 | 57 | |
58 | 58 | CCM is a encrypt+authenticate mode that is centered around using AES (or any 16-byte cipher) as aprimitive. |
71 | 71 | =head2 ccm_encrypt_authenticate |
72 | 72 | |
73 | 73 | my ($ciphertext, $tag) = ccm_encrypt_authenticate($cipher, $key, $nonce, $header, $tag_len, $plaintext); |
74 | ||
74 | ||
75 | 75 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
76 | 76 | # $key ..... AES key of proper length (128/192/256bits) |
77 | 77 | # $nonce ... unique nonce/salt (no need to keep it secret) |
80 | 80 | =head2 ccm_decrypt_verify |
81 | 81 | |
82 | 82 | my $plaintext = ccm_decrypt_verify($cipher, $key, $nonce, $header, $ciphertext, $tag); |
83 | ||
83 | ||
84 | 84 | # on error returns undef |
85 | 85 | |
86 | 86 | =head1 SEE ALSO |
29 | 29 | my $nonce = shift; |
30 | 30 | my $header = shift; |
31 | 31 | my $plaintext = shift; |
32 | ||
32 | ||
33 | 33 | my $m = Crypt::AuthEnc::EAX->new($cipher_name, $key, $nonce); |
34 | 34 | $m->header_add($header) if defined $header; |
35 | 35 | my $ct = $m->encrypt_add($plaintext); |
64 | 64 | |
65 | 65 | ### example 1 |
66 | 66 | use Crypt::AuthEnc::EAX; |
67 | ||
67 | ||
68 | 68 | # encrypt + authenticate |
69 | 69 | my $ae = Crypt::AuthEnc::EAX->new("AES", $key, $nonce); |
70 | 70 | $ae->header_add('headerdata part1'); |
89 | 89 | |
90 | 90 | ### example 2 |
91 | 91 | use Crypt::AuthEnc::EAX qw(eax_encrypt_authenticate eax_decrypt_verify); |
92 | ||
92 | ||
93 | 93 | my ($ciphertext, $tag) = eax_encrypt_authenticate('AES', $key, $nonce, $header, $plaintext); |
94 | 94 | my $plaintext = eax_decrypt_verify('AES', $key, $nonce, $header, $ciphertext, $tag); |
95 | 95 | |
96 | 96 | =head1 DESCRIPTION |
97 | 97 | |
98 | EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication. | |
98 | EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication. | |
99 | 99 | It is initialized with a random nonce that can be shared publicly, a header which can be fixed and public, |
100 | 100 | and a random secret symmetric key. |
101 | 101 | |
112 | 112 | =head2 eax_encrypt_authenticate |
113 | 113 | |
114 | 114 | my ($ciphertext, $tag) = eax_encrypt_authenticate($cipher, $key, $nonce, $header, $plaintext); |
115 | ||
115 | ||
116 | 116 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
117 | 117 | # $key ..... AES key of proper length (128/192/256bits) |
118 | 118 | # $nonce ... unique nonce/salt (no need to keep it secret) |
121 | 121 | =head2 eax_decrypt_verify |
122 | 122 | |
123 | 123 | my $plaintext = eax_decrypt_verify($cipher, $key, $nonce, $header, $ciphertext, $tag); |
124 | ||
124 | ||
125 | 125 | # on error returns undef |
126 | 126 | |
127 | 127 | =head1 METHODS |
131 | 131 | my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $nonce); |
132 | 132 | #or |
133 | 133 | my $ae = Crypt::AuthEnc::EAX->new($cipher, $key, $nonce, $header); |
134 | ||
134 | ||
135 | 135 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
136 | 136 | # $key ..... AES key of proper length (128/192/256bits) |
137 | 137 | # $nonce ... unique nonce/salt (no need to keep it secret) |
19 | 19 | my $iv = shift; |
20 | 20 | my $adata = shift; |
21 | 21 | my $plaintext = shift; |
22 | ||
22 | ||
23 | 23 | my $m = Crypt::AuthEnc::GCM->new($cipher_name, $key); |
24 | 24 | $m->iv_add($iv); |
25 | 25 | $m->adata_add(defined $adata ? $adata : ''); #XXX-TODO if no aad we have to pass empty string |
54 | 54 | =head1 SYNOPSIS |
55 | 55 | |
56 | 56 | ### OO interface |
57 | ||
57 | ||
58 | 58 | # encrypt and authenticate |
59 | 59 | my $ae = Crypt::AuthEnc::GCM->new("AES", $key); |
60 | 60 | $ae->iv_add('data_iv1'); |
79 | 79 | |
80 | 80 | ### functional interface |
81 | 81 | use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify); |
82 | ||
82 | ||
83 | 83 | my ($ciphertext, $tag) = gcm_encrypt_authenticate('AES', $key, $iv, $adata, $plaintext); |
84 | 84 | my $plaintext = gcm_decrypt_verify('AES', $key, $iv, $adata, $ciphertext, $tag); |
85 | ||
85 | ||
86 | 86 | =head1 DESCRIPTION |
87 | 87 | |
88 | Galois/Counter Mode (GCM) - provides encryption and authentication. | |
88 | Galois/Counter Mode (GCM) - provides encryption and authentication. | |
89 | 89 | |
90 | 90 | =head1 EXPORT |
91 | 91 | |
100 | 100 | =head2 gcm_encrypt_authenticate |
101 | 101 | |
102 | 102 | my ($ciphertext, $tag) = gcm_encrypt_authenticate($cipher, $key, $iv, $adata, $plaintext); |
103 | ||
103 | ||
104 | 104 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
105 | 105 | # $key ..... AES key of proper length (128/192/256bits) |
106 | 106 | # $iv ...... initial vector |
109 | 109 | =head2 gcm_decrypt_verify |
110 | 110 | |
111 | 111 | my $plaintext = gcm_decrypt_verify($cipher, $key, $iv, $adata, $ciphertext, $tag); |
112 | ||
112 | ||
113 | 113 | # on error returns undef |
114 | 114 | |
115 | 115 | =head1 METHODS |
117 | 117 | =head2 new |
118 | 118 | |
119 | 119 | my $ae = Crypt::AuthEnc::GCM->new($cipher, $key); |
120 | ||
120 | ||
121 | 121 | # $cipher .. 'AES' or name of any other cipher |
122 | 122 | # $key ..... encryption key of proper length |
123 | 123 |
19 | 19 | my $nonce = shift; |
20 | 20 | my $aad = shift; |
21 | 21 | my $plaintext = shift; |
22 | ||
22 | ||
23 | 23 | my $m = Crypt::AuthEnc::OCB->new($cipher_name, $key, $nonce); |
24 | 24 | $m->adata_add($aad) if defined $aad; |
25 | 25 | my $ct = $m->encrypt_last($plaintext); |
53 | 53 | |
54 | 54 | ### OO interface |
55 | 55 | use Crypt::AuthEnc::OCB; |
56 | ||
56 | ||
57 | 57 | my $ae = Crypt::AuthEnc::OCB->new("AES", $key, $nonce); |
58 | 58 | $ae->adata_add('aad1'); |
59 | 59 | $ae->adata_add('aad2'); |
74 | 74 | |
75 | 75 | ### functional interface |
76 | 76 | use Crypt::AuthEnc::OCB qw(ocb_encrypt_authenticate ocb_decrypt_verify); |
77 | ||
77 | ||
78 | 78 | my ($ciphertext, $tag) = ocb_encrypt_authenticate('AES', $key, $nonce, $aad, $plaintext); |
79 | 79 | my $plaintext = ocb_decrypt_verify('AES', $key, $nonce, $aad, $ciphertext, $tag); |
80 | 80 | |
95 | 95 | =head2 ocb_encrypt_authenticate |
96 | 96 | |
97 | 97 | my ($ciphertext, $tag) = ocb_encrypt_authenticate($cipher, $key, $nonce, $aad, $plaintext); |
98 | ||
98 | ||
99 | 99 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
100 | 100 | # $key ..... AES key of proper length (128/192/256bits) |
101 | 101 | # $nonce ... unique nonce/salt (no need to keep it secret) |
104 | 104 | =head2 ocb_decrypt_verify |
105 | 105 | |
106 | 106 | my $plaintext = ocb_decrypt_verify($cipher, $key, $nonce, $aad, $ciphertext, $tag); |
107 | ||
107 | ||
108 | 108 | # on error returns undef |
109 | 109 | |
110 | 110 | =head1 METHODS |
112 | 112 | =head2 new |
113 | 113 | |
114 | 114 | my $ae = Crypt::AuthEnc::OCB->new($cipher, $key, $nonce); |
115 | ||
115 | ||
116 | 116 | # $cipher .. 'AES' or name of any other cipher with 16-byte block len |
117 | 117 | # $key ..... AES key of proper length (128/192/256bits) |
118 | 118 | # $nonce ... unique nonce/salt (no need to keep it secret) |
124 | 124 | =head2 encrypt_add |
125 | 125 | |
126 | 126 | $ciphertext = $ae->encrypt_add($data); #can be called multiple times |
127 | ||
127 | ||
128 | 128 | #BEWARE: size of $data has to be multiple of blocklen (16 for AES) |
129 | 129 | |
130 | 130 | =head2 encrypt_last |
138 | 138 | =head2 decrypt_add |
139 | 139 | |
140 | 140 | $plaintext = $ae->decrypt_add($ciphertext); #can be called multiple times |
141 | ||
141 | ||
142 | 142 | #BEWARE: size of $ciphertext has to be multiple of blocklen (16 for AES) |
143 | 143 | |
144 | 144 | =head2 encrypt_last |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('AES'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::AES; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Anubis'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Anubis; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Anubis', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Blowfish'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Blowfish; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Blowfish', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('CAST5'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::CAST5; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::CAST5', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Camellia'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Camellia; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Camellia', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('DES'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::DES; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('DES_EDE'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::DES_EDE; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::DES_EDE', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('KASUMI'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::KASUMI; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::KASUMI', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Khazad'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Khazad; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Khazad', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('MULTI2'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::MULTI2; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::MULTI2', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Noekeon'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Noekeon; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Noekeon', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('RC2'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::RC2; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC2', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('RC5'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::RC5; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC5', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('RC6'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::RC6; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::RC6', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SAFERP'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SAFERP; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFERP', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SAFER_K128'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SAFER_K128; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K128', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SAFER_K64'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SAFER_K64; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_K64', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SAFER_SK128'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SAFER_SK128; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK128', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SAFER_SK64'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SAFER_SK64; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SAFER_SK64', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('SEED'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::SEED; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::SEED', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Skipjack'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Skipjack; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Skipjack', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('Twofish'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::Twofish; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::Twofish', -key=>$key, -iv=>$iv ); |
25 | 25 | |
26 | 26 | ### example 1 |
27 | 27 | use Crypt::Mode::CBC; |
28 | ||
28 | ||
29 | 29 | my $key = '...'; # length has to be valid key size for this cipher |
30 | 30 | my $iv = '...'; # 16 bytes |
31 | 31 | my $cbc = Crypt::Mode::CBC->new('XTEA'); |
34 | 34 | ### example 2 |
35 | 35 | use Crypt::CBC; |
36 | 36 | use Crypt::Cipher::XTEA; |
37 | ||
37 | ||
38 | 38 | my $key = '...'; # length has to be valid key size for this cipher |
39 | 39 | my $iv = '...'; # 16 bytes |
40 | 40 | my $cbc = Crypt::CBC->new( -cipher=>'Cipher::XTEA', -key=>$key, -iv=>$iv ); |
14 | 14 | # - encrypt |
15 | 15 | # - decrypt |
16 | 16 | #functions, not methods: |
17 | # - _block_length_by_name | |
17 | # - _block_length_by_name | |
18 | 18 | # - _min_key_length_by_name |
19 | 19 | # - _max_key_length_by_name |
20 | 20 | # - _default_rounds_by_name |
25 | 25 | DES_EDE => '3des', |
26 | 26 | SAFERP => 'safer+', |
27 | 27 | SAFER_K128 => 'safer-k128', |
28 | SAFER_K64 => 'safer-k64', | |
28 | SAFER_K64 => 'safer-k64', | |
29 | 29 | SAFER_SK128 => 'safer-sk128', |
30 | 30 | SAFER_SK64 => 'safer-sk64', |
31 | 31 | ); |
42 | 42 | return _new($cipher_name, @_); |
43 | 43 | } |
44 | 44 | |
45 | sub blocksize { | |
45 | sub blocksize { | |
46 | 46 | my $self = shift; |
47 | 47 | return $self->_blocksize if ref($self); |
48 | 48 | $self = _trans_cipher_name(shift) if $self eq __PACKAGE__; |
49 | 49 | return _block_length_by_name(_trans_cipher_name($self)); |
50 | 50 | } |
51 | ||
52 | sub keysize { | |
51 | ||
52 | sub keysize { | |
53 | 53 | max_keysize(@_); |
54 | 54 | } |
55 | 55 | |
92 | 92 | |
93 | 93 | #### example 1 |
94 | 94 | use Crypt::Cipher; |
95 | ||
95 | ||
96 | 96 | $key = 'K' x 32; # 256 bits |
97 | 97 | $c = Crypt::Cipher->new('AES', $key); |
98 | 98 | $blocksize = $c->blocksize; |
99 | 99 | $ciphertext = $c->encrypt('plain text block'); #encrypt 1 block |
100 | 100 | $plaintext = $c->decrypt($ciphertext); #decrypt 1 block |
101 | ||
101 | ||
102 | 102 | #### example 2 (compatibility with Crypt::CBC) |
103 | 103 | use Crypt::CBC; |
104 | 104 | use Crypt::Cipher; |
105 | ||
105 | ||
106 | 106 | my $key = '...'; # length has to be valid key size for this cipher |
107 | 107 | my $cipher = Crypt::Cipher('AES', $key); |
108 | 108 | my $cbc = Crypt::CBC->new( -cipher=>$cipher ); |
109 | 109 | my $ciphertext = $cbc->encrypt("secret data"); |
110 | ||
110 | ||
111 | 111 | =head1 DESCRIPTION |
112 | 112 | |
113 | 113 | Provides an interface to various symetric cipher algorithms. |
114 | 114 | |
115 | B<BEWARE:> This module implements just elementary one-block (usually 8 or 16 byte) encryption/encryption | |
115 | B<BEWARE:> This module implements just elementary one-block (usually 8 or 16 byte) encryption/encryption | |
116 | 116 | operation - if you want to encrypt/decrypt generic data of "any length" you have to use some of the cipher |
117 | 117 | block modes - check for example L<Crypt::Mode::CBC|Crypt::Mode::CBC>. |
118 | 118 | |
124 | 124 | |
125 | 125 | ## basic scenario |
126 | 126 | $d = Crypt::Cipher->new($name, $key); |
127 | # $name = one of 'AES', 'Anubis', 'Blowfish', 'CAST5', 'Camellia', 'DES', 'DES_EDE', | |
128 | # 'KASUMI', 'Khazad', 'MULTI2', 'Noekeon', 'RC2', 'RC5', 'RC6', | |
127 | # $name = one of 'AES', 'Anubis', 'Blowfish', 'CAST5', 'Camellia', 'DES', 'DES_EDE', | |
128 | # 'KASUMI', 'Khazad', 'MULTI2', 'Noekeon', 'RC2', 'RC5', 'RC6', | |
129 | 129 | # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64', |
130 | 130 | # 'SEED', 'Skipjack', 'Twofish', 'XTEA' |
131 | 131 | # simply any <CNAME> for which there exists Crypt::Cipher::<NAME> |
132 | 132 | # $key = binary key (keysize should comply with selected cipher requirements) |
133 | ||
133 | ||
134 | 134 | ## some of the ciphers (e.g. MULTI2, RC5, SAFER) allows to set number of rounds |
135 | 135 | $d = Crypt::Cipher->new('MULTI2', $key, $rounds); |
136 | 136 | # $rounds = positive integer (should comply with selected cipher requirements) |
190 | 190 | Crypt::Cipher->default_rounds('AES'); |
191 | 191 | #or |
192 | 192 | Crypt::Cipher::default_rounds('AES'); |
193 | ||
193 | ||
194 | 194 | =head1 SEE ALSO |
195 | 195 | |
196 | 196 | =over 4 |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u | |
40 | use Crypt::Digest::CHAES qw( chaes chaes_hex chaes_b64 chaes_b64u | |
41 | 41 | chaes_file chaes_file_hex chaes_file_b64 chaes_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u | |
40 | use Crypt::Digest::MD2 qw( md2 md2_hex md2_b64 md2_b64u | |
41 | 41 | md2_file md2_file_hex md2_file_b64 md2_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u | |
40 | use Crypt::Digest::MD4 qw( md4 md4_hex md4_b64 md4_b64u | |
41 | 41 | md4_file md4_file_hex md4_file_b64 md4_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u | |
40 | use Crypt::Digest::MD5 qw( md5 md5_hex md5_b64 md5_b64u | |
41 | 41 | md5_file md5_file_hex md5_file_b64 md5_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u | |
40 | use Crypt::Digest::RIPEMD128 qw( ripemd128 ripemd128_hex ripemd128_b64 ripemd128_b64u | |
41 | 41 | ripemd128_file ripemd128_file_hex ripemd128_file_b64 ripemd128_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u | |
40 | use Crypt::Digest::RIPEMD160 qw( ripemd160 ripemd160_hex ripemd160_b64 ripemd160_b64u | |
41 | 41 | ripemd160_file ripemd160_file_hex ripemd160_file_b64 ripemd160_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u | |
40 | use Crypt::Digest::RIPEMD256 qw( ripemd256 ripemd256_hex ripemd256_b64 ripemd256_b64u | |
41 | 41 | ripemd256_file ripemd256_file_hex ripemd256_file_b64 ripemd256_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u | |
40 | use Crypt::Digest::RIPEMD320 qw( ripemd320 ripemd320_hex ripemd320_b64 ripemd320_b64u | |
41 | 41 | ripemd320_file ripemd320_file_hex ripemd320_file_b64 ripemd320_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u | |
40 | use Crypt::Digest::SHA1 qw( sha1 sha1_hex sha1_b64 sha1_b64u | |
41 | 41 | sha1_file sha1_file_hex sha1_file_b64 sha1_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u | |
40 | use Crypt::Digest::SHA224 qw( sha224 sha224_hex sha224_b64 sha224_b64u | |
41 | 41 | sha224_file sha224_file_hex sha224_file_b64 sha224_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u | |
40 | use Crypt::Digest::SHA256 qw( sha256 sha256_hex sha256_b64 sha256_b64u | |
41 | 41 | sha256_file sha256_file_hex sha256_file_b64 sha256_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u | |
40 | use Crypt::Digest::SHA384 qw( sha384 sha384_hex sha384_b64 sha384_b64u | |
41 | 41 | sha384_file sha384_file_hex sha384_file_b64 sha384_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u | |
40 | use Crypt::Digest::SHA512 qw( sha512 sha512_hex sha512_b64 sha512_b64u | |
41 | 41 | sha512_file sha512_file_hex sha512_file_b64 sha512_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u | |
40 | use Crypt::Digest::Tiger192 qw( tiger192 tiger192_hex tiger192_b64 tiger192_b64u | |
41 | 41 | tiger192_file tiger192_file_hex tiger192_file_b64 tiger192_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
37 | 37 | =head1 SYNOPSIS |
38 | 38 | |
39 | 39 | ### Functional interface: |
40 | use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u | |
40 | use Crypt::Digest::Whirlpool qw( whirlpool whirlpool_hex whirlpool_b64 whirlpool_b64u | |
41 | 41 | whirlpool_file whirlpool_file_hex whirlpool_file_b64 whirlpool_file_b64u ); |
42 | 42 | |
43 | 43 | # calculate digest from string/buffer |
56 | 56 | } |
57 | 57 | else { |
58 | 58 | my $pkg = shift; |
59 | unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); | |
59 | unshift @_, ($pkg eq 'Crypt::Digest' ? _trans_digest_name(shift) : _trans_digest_name($pkg)); | |
60 | 60 | ###return _hashsize_by_name(@_); |
61 | 61 | goto \&_hashsize_by_name; # keep the real caller for croak() |
62 | 62 | } |
64 | 64 | |
65 | 65 | sub addfile { |
66 | 66 | my ($self, $file) = @_; |
67 | ||
67 | ||
68 | 68 | my $handle; |
69 | 69 | if (ref(\$file) eq 'SCALAR') { #filename |
70 | 70 | open($handle, "<", $file) || croak "FATAL: cannot open '$file': $!"; |
71 | 71 | binmode($handle); |
72 | 72 | } |
73 | else { #handle | |
73 | else { #handle | |
74 | 74 | $handle = $file |
75 | } | |
75 | } | |
76 | 76 | croak "FATAL: invalid handle" unless defined $handle; |
77 | ||
77 | ||
78 | 78 | my $n; |
79 | 79 | my $buf = ""; |
80 | 80 | while (($n = read($handle, $buf, 32*1024))) { |
81 | 81 | $self->add($buf) |
82 | 82 | } |
83 | 83 | croak "FATAL: read failed: $!" unless defined $n; |
84 | ||
84 | ||
85 | 85 | return $self; |
86 | 86 | } |
87 | 87 | |
119 | 119 | ### Functional interface: |
120 | 120 | use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u |
121 | 121 | digest_file digest_file_hex digest_file_b64 digest_file_b64u ); |
122 | ||
122 | ||
123 | 123 | # calculate digest from string/buffer |
124 | 124 | $digest_raw = digest_data('SHA1', 'data string'); |
125 | 125 | $digest_hex = digest_data_hex('SHA1', 'data string'); |
126 | $digest_b64 = digest_data_b64('SHA1', 'data string'); | |
127 | $digest_b64u = digest_data_b64u('SHA1', 'data string'); | |
126 | $digest_b64 = digest_data_b64('SHA1', 'data string'); | |
127 | $digest_b64u = digest_data_b64u('SHA1', 'data string'); | |
128 | 128 | # calculate digest from file |
129 | 129 | $digest_raw = digest_file('SHA1', 'filename.dat'); |
130 | 130 | $digest_hex = digest_file_hex('SHA1', 'filename.dat'); |
133 | 133 | # calculate digest from filehandle |
134 | 134 | $digest_raw = digest_file('SHA1', *FILEHANDLE); |
135 | 135 | $digest_hex = digest_file_hex('SHA1', *FILEHANDLE); |
136 | $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); | |
137 | $digest_b64u = digest_file_b64u('SHA1', *FILEHANDLE); | |
136 | $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); | |
137 | $digest_b64u = digest_file_b64u('SHA1', *FILEHANDLE); | |
138 | 138 | |
139 | 139 | ### OO interface: |
140 | 140 | use Crypt::Digest; |
141 | ||
141 | ||
142 | 142 | $d = Crypt::Digest->new('SHA1'); |
143 | 143 | $d->add('any data'); |
144 | 144 | $d->addfile('filename.dat'); |
147 | 147 | $result_hex = $d->hexdigest; # hexadecimal form |
148 | 148 | $result_b64 = $d->b64digest; # Base64 form |
149 | 149 | $result_b64u = $d->b64udigest; # Base64 URL Safe form |
150 | ||
150 | ||
151 | 151 | =head1 DESCRIPTION |
152 | 152 | |
153 | 153 | Provides an interface to various hash/digest algorithms. |
160 | 160 | |
161 | 161 | use Crypt::Digest qw( digest_data digest_data_hex digest_data_b64 digest_data_b64u |
162 | 162 | digest_file digest_file_hex digest_file_b64 digest_file_b64u ); |
163 | ||
163 | ||
164 | 164 | Or all of them at once: |
165 | 165 | |
166 | 166 | use Crypt::Digest ':all'; |
167 | ||
167 | ||
168 | 168 | =head1 FUNCTIONS |
169 | 169 | |
170 | 170 | Please note that all functions take as its first argument the algoritm name, supported values are: |
171 | 171 | |
172 | 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', | |
172 | 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', | |
173 | 173 | 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', |
174 | 174 | 'SHA384', 'SHA512', 'Tiger192', 'Whirlpool' |
175 | ||
175 | ||
176 | 176 | (simply any <FUNCNAME> for which there is Crypt::Digest::<FUNCNAME> module) |
177 | 177 | |
178 | 178 | =head2 digest_data |
180 | 180 | Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a binary string. |
181 | 181 | |
182 | 182 | $digest_raw = digest_data('SHA1', 'data string'); |
183 | #or | |
183 | #or | |
184 | 184 | $digest_raw = digest_data('SHA1', 'any data', 'more data', 'even more data'); |
185 | 185 | |
186 | 186 | =head2 digest_data_hex |
188 | 188 | Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a hexadecimal string. |
189 | 189 | |
190 | 190 | $digest_hex = digest_data_hex('SHA1', 'data string'); |
191 | #or | |
191 | #or | |
192 | 192 | $digest_hex = digest_data_hex('SHA1', 'any data', 'more data', 'even more data'); |
193 | 193 | |
194 | 194 | =head2 digest_data_b64 |
196 | 196 | Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 string, B<with> trailing '=' padding. |
197 | 197 | |
198 | 198 | $digest_b64 = digest_data_b64('SHA1', 'data string'); |
199 | #or | |
199 | #or | |
200 | 200 | $digest_b64 = digest_data_b64('SHA1', 'any data', 'more data', 'even more data'); |
201 | 201 | |
202 | 202 | =head2 digest_data_b64u |
204 | 204 | Logically joins all arguments into a single string, and returns its SHA1 digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). |
205 | 205 | |
206 | 206 | $digest_b64url = digest_data_b64u('SHA1', 'data string'); |
207 | #or | |
207 | #or | |
208 | 208 | $digest_b64url = digest_data_b64u('SHA1', 'any data', 'more data', 'even more data'); |
209 | 209 | |
210 | 210 | =head2 digest_file |
233 | 233 | #or |
234 | 234 | $digest_b64 = digest_file_b64('SHA1', *FILEHANDLE); |
235 | 235 | |
236 | =head2 digest_file_b64u | |
236 | =head2 digest_file_b64u | |
237 | 237 | |
238 | 238 | Reads file (defined by filename or filehandle) content, and returns its digest encoded as a Base64 URL Safe string (see RFC 4648 section 5). |
239 | 239 | |
248 | 248 | Constructor, returns a reference to the digest object. |
249 | 249 | |
250 | 250 | $d = Crypt::Digest->new($name); |
251 | # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', | |
252 | # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', | |
251 | # $name could be: 'CHAES', 'MD2', 'MD4', 'MD5', 'RIPEMD128', 'RIPEMD160', | |
252 | # 'RIPEMD256', 'RIPEMD320', 'SHA1', 'SHA224', 'SHA256', | |
253 | 253 | # 'SHA384', 'SHA512', 'Tiger192', 'Whirlpool' |
254 | 254 | # |
255 | 255 | # simply any <FUNCNAME> for which there is Crypt::Digest::<FUNCNAME> module |
274 | 274 | $d->add('any data'); |
275 | 275 | #or |
276 | 276 | $d->add('any data', 'more data', 'even more data'); |
277 | ||
277 | ||
278 | 278 | Note that all the following cases are equivalent: |
279 | 279 | |
280 | 280 | # case 1 |
281 | 281 | $d->add('aa', 'bb', 'cc'); |
282 | ||
282 | ||
283 | 283 | # case 2 |
284 | 284 | $d->add('aa'); |
285 | 285 | $d->add('bb'); |
71 | 71 | |
72 | 72 | ### HKDF & co. |
73 | 73 | $derived_key3 = hkdf($keying_material, $salt, $hash_name, $len, $info); |
74 | $prk = hkdf_extract($keying_material, $salt, $hash_name); | |
74 | $prk = hkdf_extract($keying_material, $salt, $hash_name); | |
75 | 75 | $okm1 = hkdf_expand($prk, $hash_name, $len, $info); |
76 | 76 | |
77 | 77 | =head1 DESCRIPTION |
99 | 99 | $derived_key = pbkdf1($password, $salt, $iteration_count); |
100 | 100 | #or |
101 | 101 | $derived_key = pbkdf1($password, $salt); |
102 | ||
102 | ||
103 | 103 | # $password ......... input keying material (password) |
104 | 104 | # $salt ............. salt/nonce (expected length: 8) |
105 | 105 | # $iteration_count .. optional, DEFAULT: 5000 |
115 | 115 | $derived_key = pbkdf2($password, $salt, $iteration_count); |
116 | 116 | #or |
117 | 117 | $derived_key = pbkdf2($password, $salt); |
118 | ||
118 | ||
119 | 119 | # $password ......... input keying material (password) |
120 | 120 | # $salt ............. salt/nonce |
121 | 121 | # $iteration_count .. optional, DEFAULT: 5000 |
143 | 143 | $prk = hkdf_extract($password, $salt, $hash_name); |
144 | 144 | #or |
145 | 145 | $prk = hkdf_extract($password, $salt, $hash_name); |
146 | ||
146 | ||
147 | 147 | # $password ... input keying material (password) |
148 | 148 | # $salt ....... salt/nonce, if undef defaults to HashLen zero octets |
149 | 149 | # $hash_name .. optional, DEFAULT: 'SHA256' |
15 | 15 | |
16 | 16 | sub addfile { |
17 | 17 | my ($self, $file) = @_; |
18 | ||
18 | ||
19 | 19 | my $handle; |
20 | 20 | if (ref(\$file) eq 'SCALAR') { |
21 | 21 | #filename |
25 | 25 | else { |
26 | 26 | #handle |
27 | 27 | $handle = $file |
28 | } | |
28 | } | |
29 | 29 | die "FATAL: invalid handle" unless defined $handle; |
30 | ||
30 | ||
31 | 31 | my $n; |
32 | 32 | my $buf = ""; |
33 | 33 | while (($n = read($handle, $buf, 32*1024))) { |
34 | 34 | $self->_add_single($buf) |
35 | 35 | } |
36 | 36 | die "FATAL: read failed: $!" unless defined $n; |
37 | ||
37 | ||
38 | 38 | return $self; |
39 | 39 | } |
40 | 40 |
56 | 56 | # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT |
57 | 57 | # 2 Crypt::CBC's "oneandzeroes" |
58 | 58 | # $cipher_rounds ... optional num of rounds for given cipher |
59 | ||
59 | ||
60 | 60 | =head2 encrypt |
61 | 61 | |
62 | 62 | my $ciphertext = $m->encrypt($plaintext, $key, $iv); |
49 | 49 | my $m = Crypt::Mode::CFB->new('AES', $cipher_rounds); |
50 | 50 | |
51 | 51 | # $cipher_rounds ... optional num of rounds for given cipher |
52 | ||
52 | ||
53 | 53 | =head2 encrypt |
54 | 54 | |
55 | 55 | my $ciphertext = $m->encrypt($plaintext, $key, $iv); |
49 | 49 | my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width); |
50 | 50 | #or |
51 | 51 | my $m = Crypt::Mode::CTR->new($cipher_name, $ctr_mode, $ctr_width, $cipher_rounds); |
52 | ||
52 | ||
53 | 53 | # $ctr_mode .... 0 little-endian counter (DEFAULT) |
54 | 54 | # 1 big-endian counter |
55 | 55 | # 2 little-endian + RFC3686 incrementing |
56 | 56 | # 3 big-endian + RFC3686 incrementing |
57 | 57 | # $ctr_width ... counter width in bytes (DEFAULT = full block width) |
58 | 58 | # $cipher_rounds ... optional num of rounds for given cipher |
59 | ||
59 | ||
60 | 60 | =head2 encrypt |
61 | 61 | |
62 | 62 | my $ciphertext = $m->encrypt($plaintext, $key, $iv); |
57 | 57 | # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT |
58 | 58 | # 2 Crypt::CBC's "oneandzeroes" |
59 | 59 | # $cipher_rounds ... optional num of rounds for given cipher |
60 | ||
60 | ||
61 | 61 | =head2 encrypt |
62 | 62 | |
63 | 63 | my $ciphertext = $m->encrypt($plaintext, $key); |
49 | 49 | my $m = Crypt::Mode::OFB->new('AES', $cipher_rounds); |
50 | 50 | |
51 | 51 | # $cipher_rounds ... optional num of rounds for given cipher |
52 | ||
52 | ||
53 | 53 | =head2 encrypt |
54 | 54 | |
55 | 55 | my $ciphertext = $m->encrypt($plaintext, $key, $iv); |
12 | 12 | use Carp; |
13 | 13 | use MIME::Base64 qw(encode_base64 decode_base64); |
14 | 14 | |
15 | sub new { | |
15 | sub new { | |
16 | 16 | my ($class, $f) = @_; |
17 | 17 | my $self = _new(); |
18 | 18 | $self->import_key($f) if $f; |
45 | 45 | |
46 | 46 | sub encrypt { |
47 | 47 | my ($self, $data, $hash_name) = @_; |
48 | $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); | |
48 | $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); | |
49 | 49 | return $self->_encrypt($data, $hash_name); |
50 | 50 | } |
51 | 51 | |
52 | 52 | sub decrypt { |
53 | my ($self, $data) = @_; | |
53 | my ($self, $data) = @_; | |
54 | 54 | return $self->_decrypt($data); |
55 | 55 | } |
56 | 56 | |
74 | 74 | } |
75 | 75 | |
76 | 76 | sub verify_hash { |
77 | my ($self, $sig, $data_hash) = @_; | |
77 | my ($self, $sig, $data_hash) = @_; | |
78 | 78 | return $self->_verify($sig, $data_hash); |
79 | 79 | } |
80 | 80 | |
90 | 90 | sub dh_decrypt { |
91 | 91 | my $key = shift; |
92 | 92 | $key = __PACKAGE__->new($key) unless ref $key; |
93 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
93 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
94 | 94 | return $key->decrypt(@_); |
95 | 95 | } |
96 | 96 | |
97 | 97 | sub dh_sign_message { |
98 | 98 | my $key = shift; |
99 | 99 | $key = __PACKAGE__->new($key) unless ref $key; |
100 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
100 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
101 | 101 | return $key->sign_message(@_); |
102 | 102 | } |
103 | 103 | |
104 | 104 | sub dh_verify_message { |
105 | 105 | my $key = shift; |
106 | 106 | $key = __PACKAGE__->new($key) unless ref $key; |
107 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
107 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
108 | 108 | return $key->verify_message(@_); |
109 | 109 | } |
110 | 110 | |
111 | 111 | sub dh_sign_hash { |
112 | 112 | my $key = shift; |
113 | 113 | $key = __PACKAGE__->new($key) unless ref $key; |
114 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
114 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
115 | 115 | return $key->sign_hash(@_); |
116 | 116 | } |
117 | 117 | |
118 | 118 | sub dh_verify_hash { |
119 | 119 | my $key = shift; |
120 | 120 | $key = __PACKAGE__->new($key) unless ref $key; |
121 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
121 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
122 | 122 | return $key->verify_hash(@_); |
123 | 123 | } |
124 | 124 | |
154 | 154 | =head1 SYNOPSIS |
155 | 155 | |
156 | 156 | ### OO interface |
157 | ||
157 | ||
158 | 158 | #Encryption: Alice |
159 | my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); | |
159 | my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); | |
160 | 160 | my $ct = $pub->encrypt("secret message"); |
161 | 161 | # |
162 | 162 | #Encryption: Bob (received ciphertext $ct) |
163 | 163 | my $priv = Crypt::PK::DH->new('Bob_priv_dh1.key'); |
164 | 164 | my $pt = $priv->decrypt($ct); |
165 | ||
165 | ||
166 | 166 | #Signature: Alice |
167 | 167 | my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); |
168 | 168 | my $sig = $priv->sign_message($message); |
170 | 170 | #Signature: Bob (received $message + $sig) |
171 | 171 | my $pub = Crypt::PK::DH->new('Alice_pub_dh1.key'); |
172 | 172 | $pub->verify_message($sig, $message) or die "ERROR"; |
173 | ||
173 | ||
174 | 174 | #Shared secret |
175 | 175 | my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key'); |
176 | my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); | |
176 | my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key'); | |
177 | 177 | my $shared_secret = $priv->shared_secret($pub); |
178 | 178 | |
179 | 179 | #Key generation |
181 | 181 | $pk->generate_key(128); |
182 | 182 | my $private = $pk->export_key('private'); |
183 | 183 | my $public = $pk->export_key('public'); |
184 | ||
184 | ||
185 | 185 | ### Functional interface |
186 | ||
186 | ||
187 | 187 | #Encryption: Alice |
188 | 188 | my $ct = dh_encrypt('Bob_pub_dh1.key', "secret message"); |
189 | 189 | #Encryption: Bob (received ciphertext $ct) |
190 | 190 | my $pt = dh_decrypt('Bob_priv_dh1.key', $ct); |
191 | ||
191 | ||
192 | 192 | #Signature: Alice |
193 | 193 | my $sig = dh_sign_message('Alice_priv_dh1.key', $message); |
194 | 194 | #Signature: Bob (received $message + $sig) |
195 | 195 | dh_verify_message('Alice_pub_dh1.key', $sig, $message) or die "ERROR"; |
196 | ||
196 | ||
197 | 197 | #Shared secret |
198 | 198 | my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); |
199 | 199 | |
208 | 208 | my $ct = dh_encrypt(\$buffer_containing_pub_key, $message); |
209 | 209 | #or |
210 | 210 | my $ct = dh_encrypt($pub_key_filename, $message, $hash_name); |
211 | ||
211 | ||
212 | 212 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
213 | ||
213 | ||
214 | 214 | Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DH key is computed, and |
215 | 215 | the hash of the shared key XOR'ed against the plaintext forms the ciphertext. |
216 | 216 | |
264 | 264 | |
265 | 265 | #on Alice side |
266 | 266 | my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key'); |
267 | ||
267 | ||
268 | 268 | #on Bob side |
269 | 269 | my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key'); |
270 | 270 | |
315 | 315 | my $ct = $pk->encrypt($message); |
316 | 316 | #or |
317 | 317 | my $ct = $pk->encrypt($message, $hash_name); |
318 | ||
318 | ||
319 | 319 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
320 | 320 | |
321 | 321 | =head2 decrypt |
378 | 378 | =head2 key2hash |
379 | 379 | |
380 | 380 | my $hash = $pk->key2hash; |
381 | ||
381 | ||
382 | 382 | # returns hash like this (or undef if no key loaded): |
383 | 383 | { |
384 | 384 | type => 0, # integer: 1 .. private, 0 .. public |
220 | 220 | my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message); |
221 | 221 | #or |
222 | 222 | my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name); |
223 | ||
223 | ||
224 | 224 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
225 | 225 | |
226 | 226 | Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DSA key is computed, and |
328 | 328 | my $ct = $pk->encrypt($message); |
329 | 329 | #or |
330 | 330 | my $ct = $pk->encrypt($message, $hash_name); |
331 | ||
331 | ||
332 | 332 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
333 | 333 | |
334 | 334 | =head2 decrypt |
379 | 379 | =head2 key2hash |
380 | 380 | |
381 | 381 | my $hash = $pk->key2hash; |
382 | ||
382 | ||
383 | 383 | # returns hash like this (or undef if no key loaded): |
384 | 384 | { |
385 | 385 | type => 1, # integer: 1 .. private, 0 .. public |
386 | 386 | size => 256, # integer: key size in bytes |
387 | # all the rest are hex strings | |
387 | # all the rest are hex strings | |
388 | 388 | p => "AAF839A764E04D80824B79FA1F0496C093...", #prime modulus |
389 | 389 | q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #prime divisor |
390 | 390 | g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator of a subgroup of order q in GF(p) |
12 | 12 | use Carp; |
13 | 13 | use MIME::Base64 qw(encode_base64 decode_base64); |
14 | 14 | |
15 | sub new { | |
15 | sub new { | |
16 | 16 | my ($class, $f) = @_; |
17 | 17 | my $self = _new(); |
18 | 18 | $self->import_key($f) if $f; |
49 | 49 | |
50 | 50 | sub encrypt { |
51 | 51 | my ($self, $data, $hash_name) = @_; |
52 | $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); | |
52 | $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1'); | |
53 | 53 | return $self->_encrypt($data, $hash_name); |
54 | 54 | } |
55 | 55 | |
56 | 56 | sub decrypt { |
57 | my ($self, $data) = @_; | |
57 | my ($self, $data) = @_; | |
58 | 58 | return $self->_decrypt($data); |
59 | 59 | } |
60 | 60 | |
78 | 78 | } |
79 | 79 | |
80 | 80 | sub verify_hash { |
81 | my ($self, $sig, $data_hash) = @_; | |
81 | my ($self, $sig, $data_hash) = @_; | |
82 | 82 | return $self->_verify($sig, $data_hash); |
83 | 83 | } |
84 | 84 | |
94 | 94 | sub ecc_decrypt { |
95 | 95 | my $key = shift; |
96 | 96 | $key = __PACKAGE__->new($key) unless ref $key; |
97 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
97 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
98 | 98 | return $key->decrypt(@_); |
99 | 99 | } |
100 | 100 | |
101 | 101 | sub ecc_sign_message { |
102 | 102 | my $key = shift; |
103 | 103 | $key = __PACKAGE__->new($key) unless ref $key; |
104 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
104 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
105 | 105 | return $key->sign_message(@_); |
106 | 106 | } |
107 | 107 | |
108 | 108 | sub ecc_verify_message { |
109 | 109 | my $key = shift; |
110 | 110 | $key = __PACKAGE__->new($key) unless ref $key; |
111 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
111 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
112 | 112 | return $key->verify_message(@_); |
113 | 113 | } |
114 | 114 | |
115 | 115 | sub ecc_sign_hash { |
116 | 116 | my $key = shift; |
117 | 117 | $key = __PACKAGE__->new($key) unless ref $key; |
118 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
118 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
119 | 119 | return $key->sign_hash(@_); |
120 | 120 | } |
121 | 121 | |
122 | 122 | sub ecc_verify_hash { |
123 | 123 | my $key = shift; |
124 | 124 | $key = __PACKAGE__->new($key) unless ref $key; |
125 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
125 | carp "FATAL: invalid 'key' param" unless ref($key) eq __PACKAGE__; | |
126 | 126 | return $key->verify_hash(@_); |
127 | 127 | } |
128 | 128 | |
158 | 158 | =head1 SYNOPSIS |
159 | 159 | |
160 | 160 | ### OO interface |
161 | ||
161 | ||
162 | 162 | #Encryption: Alice |
163 | my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); | |
163 | my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); | |
164 | 164 | my $ct = $pub->encrypt("secret message"); |
165 | 165 | # |
166 | 166 | #Encryption: Bob (received ciphertext $ct) |
167 | 167 | my $priv = Crypt::PK::ECC->new('Bob_priv_ecc1.der'); |
168 | 168 | my $pt = $priv->decrypt($ct); |
169 | ||
169 | ||
170 | 170 | #Signature: Alice |
171 | 171 | my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); |
172 | 172 | my $sig = $priv->sign_message($message); |
174 | 174 | #Signature: Bob (received $message + $sig) |
175 | 175 | my $pub = Crypt::PK::ECC->new('Alice_pub_ecc1.der'); |
176 | 176 | $pub->verify_message($sig, $message) or die "ERROR"; |
177 | ||
177 | ||
178 | 178 | #Shared secret |
179 | 179 | my $priv = Crypt::PK::ECC->new('Alice_priv_ecc1.der'); |
180 | my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); | |
180 | my $pub = Crypt::PK::ECC->new('Bob_pub_ecc1.der'); | |
181 | 181 | my $shared_secret = $priv->shared_secret($pub); |
182 | 182 | |
183 | 183 | #Key generation |
188 | 188 | my $public_ansi_x963 = $pk->export_key_x963(); |
189 | 189 | |
190 | 190 | ### Functional interface |
191 | ||
191 | ||
192 | 192 | #Encryption: Alice |
193 | 193 | my $ct = ecc_encrypt('Bob_pub_ecc1.der', "secret message"); |
194 | 194 | #Encryption: Bob (received ciphertext $ct) |
195 | 195 | my $pt = ecc_decrypt('Bob_priv_ecc1.der', $ct); |
196 | ||
196 | ||
197 | 197 | #Signature: Alice |
198 | 198 | my $sig = ecc_sign_message('Alice_priv_ecc1.der', $message); |
199 | 199 | #Signature: Bob (received $message + $sig) |
200 | 200 | ecc_verify_message('Alice_pub_ecc1.der', $sig, $message) or die "ERROR"; |
201 | ||
201 | ||
202 | 202 | #Shared secret |
203 | 203 | my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); |
204 | 204 | |
205 | 205 | =head1 DESCRIPTION |
206 | 206 | |
207 | The module provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of | |
207 | The module provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of | |
208 | 208 | all of the Diffie-Hellman routines (ECDH). |
209 | 209 | |
210 | 210 | =head1 FUNCTIONS |
218 | 218 | my $ct = ecc_encrypt(\$buffer_containing_pub_key, $message); |
219 | 219 | #or |
220 | 220 | my $ct = ecc_encrypt($pub_key_filename, $message, $hash_name); |
221 | ||
221 | ||
222 | 222 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
223 | 223 | |
224 | 224 | ECCDH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext. |
273 | 273 | |
274 | 274 | #on Alice side |
275 | 275 | my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der'); |
276 | ||
276 | ||
277 | 277 | #on Bob side |
278 | 278 | my $shared_secret = ecc_shared_secret('Bob_priv_ecc1.der', 'Alice_pub_ecc1.der'); |
279 | 279 | |
302 | 302 | # 32 => use curve P-256 recommended by FIPS 186-3 |
303 | 303 | # 48 => use curve P-384 recommended by FIPS 186-3 |
304 | 304 | # 65 => use curve P-521 recommended by FIPS 186-3 |
305 | ||
305 | ||
306 | 306 | See L<http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf> and L<http://www.secg.org/collateral/sec2_final.pdf> |
307 | 307 | |
308 | 308 | =head2 import_key |
337 | 337 | my $ct = $pk->encrypt($message); |
338 | 338 | #or |
339 | 339 | my $ct = $pk->encrypt($message, $hash_name); |
340 | ||
340 | ||
341 | 341 | #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest |
342 | 342 | |
343 | 343 | =head2 decrypt |
400 | 400 | =head2 key2hash |
401 | 401 | |
402 | 402 | my $hash = $pk->key2hash; |
403 | ||
403 | ||
404 | 404 | # returns hash like this (or undef if no key loaded): |
405 | 405 | { |
406 | 406 | type => 1, # integer: 1 .. private, 0 .. public |
437 | 437 | =head2 key2hash |
438 | 438 | |
439 | 439 | my $hash = $pk->key2hash; |
440 | ||
440 | ||
441 | 441 | # returns hash like this (or undef if no key loaded): |
442 | 442 | { |
443 | 443 | type => 1, # integer: 1 .. private, 0 .. public |
444 | 444 | size => 256, # integer: key size in bytes |
445 | # all the rest are hex strings | |
445 | # all the rest are hex strings | |
446 | 446 | e => "10001", #public exponent |
447 | 447 | d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent |
448 | 448 | N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus |
11 | 11 | use base 'Crypt::PRNG'; |
12 | 12 | |
13 | 13 | { |
14 | ### stolen from Bytes::Random::Secure | |
14 | ### stolen from Bytes::Random::Secure | |
15 | 15 | my $RNG_object = undef; |
16 | 16 | my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. |
17 | 17 | $RNG_object = Crypt::PRNG::Fortuna->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; |
18 | 18 | return $RNG_object; |
19 | }; | |
19 | }; | |
20 | 20 | sub rand { return $fetch_RNG->()->double(@_) } |
21 | 21 | sub irand { return $fetch_RNG->()->int32(@_) } |
22 | 22 | sub random_bytes { return $fetch_RNG->()->bytes(@_) } |
58 | 58 | $prng = Crypt::PRNG::Fortuna->new; |
59 | 59 | #or |
60 | 60 | $prng = Crypt::PRNG::Fortuna->new("some data used for seeding PRNG"); |
61 | ||
61 | ||
62 | 62 | $octets = $prng->bytes(45); |
63 | 63 | $hex_string = $prng->bytes_hex(45); |
64 | 64 | $base64_string = $prng->bytes_b64(45); |
11 | 11 | use base 'Crypt::PRNG'; |
12 | 12 | |
13 | 13 | { |
14 | ### stolen from Bytes::Random::Secure | |
14 | ### stolen from Bytes::Random::Secure | |
15 | 15 | my $RNG_object = undef; |
16 | 16 | my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. |
17 | 17 | $RNG_object = Crypt::PRNG::RC4->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; |
18 | 18 | return $RNG_object; |
19 | }; | |
19 | }; | |
20 | 20 | sub rand { return $fetch_RNG->()->double(@_) } |
21 | 21 | sub irand { return $fetch_RNG->()->int32(@_) } |
22 | 22 | sub random_bytes { return $fetch_RNG->()->bytes(@_) } |
57 | 57 | $prng = Crypt::PRNG::RC4->new; |
58 | 58 | #or |
59 | 59 | $prng = Crypt::PRNG::RC4->new("some data used for seeding PRNG"); |
60 | ||
60 | ||
61 | 61 | $octets = $prng->bytes(45); |
62 | 62 | $hex_string = $prng->bytes_hex(45); |
63 | 63 | $base64_string = $prng->bytes_b64(45); |
11 | 11 | use base 'Crypt::PRNG'; |
12 | 12 | |
13 | 13 | { |
14 | ### stolen from Bytes::Random::Secure | |
14 | ### stolen from Bytes::Random::Secure | |
15 | 15 | my $RNG_object = undef; |
16 | 16 | my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. |
17 | 17 | $RNG_object = Crypt::PRNG::Sober128->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; |
18 | 18 | return $RNG_object; |
19 | }; | |
19 | }; | |
20 | 20 | sub rand { return $fetch_RNG->()->double(@_) } |
21 | 21 | sub irand { return $fetch_RNG->()->int32(@_) } |
22 | 22 | sub random_bytes { return $fetch_RNG->()->bytes(@_) } |
57 | 57 | $prng = Crypt::PRNG::Sober128->new; |
58 | 58 | #or |
59 | 59 | $prng = Crypt::PRNG::Sober128->new("some data used for seeding PRNG"); |
60 | ||
60 | ||
61 | 61 | $octets = $prng->bytes(45); |
62 | 62 | $hex_string = $prng->bytes_hex(45); |
63 | 63 | $base64_string = $prng->bytes_b64(45); |
11 | 11 | use base 'Crypt::PRNG'; |
12 | 12 | |
13 | 13 | { |
14 | ### stolen from Bytes::Random::Secure | |
14 | ### stolen from Bytes::Random::Secure | |
15 | 15 | my $RNG_object = undef; |
16 | 16 | my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. |
17 | 17 | $RNG_object = Crypt::PRNG::Yarrow->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; |
18 | 18 | return $RNG_object; |
19 | }; | |
19 | }; | |
20 | 20 | sub rand { return $fetch_RNG->()->double(@_) } |
21 | 21 | sub irand { return $fetch_RNG->()->int32(@_) } |
22 | 22 | sub random_bytes { return $fetch_RNG->()->bytes(@_) } |
57 | 57 | $prng = Crypt::PRNG::Yarrow->new; |
58 | 58 | #or |
59 | 59 | $prng = Crypt::PRNG::Yarrow->new("some data used for seeding PRNG"); |
60 | ||
60 | ||
61 | 61 | $octets = $prng->bytes(45); |
62 | 62 | $hex_string = $prng->bytes_hex(45); |
63 | 63 | $base64_string = $prng->bytes_b64(45); |
43 | 43 | |
44 | 44 | sub string_from { |
45 | 45 | my ($self, $chars, $len) = @_; |
46 | ||
46 | ||
47 | 47 | $len = 20 unless defined $len; |
48 | 48 | return unless $len>0; |
49 | ||
49 | ||
50 | 50 | my @ch = split(//, $chars); |
51 | 51 | my $max_index = scalar(@ch)-1; |
52 | ||
52 | ||
53 | 53 | my $mask; |
54 | for my $n (1..31) { | |
54 | for my $n (1..31) { | |
55 | 55 | $mask = (1<<$n) - 1; |
56 | 56 | last if $mask >= $max_index; |
57 | 57 | } |
78 | 78 | my $fetch_RNG = sub { # Lazily, instantiate the RNG object, but only once. |
79 | 79 | $RNG_object = Crypt::PRNG->new unless defined $RNG_object && ref($RNG_object) ne 'SCALAR'; |
80 | 80 | return $RNG_object; |
81 | }; | |
81 | }; | |
82 | 82 | sub rand { return $fetch_RNG->()->double(@_) } |
83 | 83 | sub irand { return $fetch_RNG->()->int32() } |
84 | 84 | sub random_bytes { return $fetch_RNG->()->bytes(@_) } |
121 | 121 | $prng = Crypt::PRNG->new("RC4"); |
122 | 122 | #or |
123 | 123 | $prng = Crypt::PRNG->new("RC4", "some data used for seeding PRNG"); |
124 | ||
124 | ||
125 | 125 | $octets = $prng->bytes(45); |
126 | 126 | $hex_string = $prng->bytes_hex(45); |
127 | 127 | $base64_string = $prng->bytes_b64(45); |
216 | 216 | If called without parameter it uses 32bytes random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32). |
217 | 217 | |
218 | 218 | B<BEWARE:> you probably do not need this function at all as the module does automatic seeding on initialization as well as reseeding after fork and thread creation. |
219 | ||
219 | ||
220 | 220 | =head2 bytes |
221 | 221 | |
222 | 222 | $octets = $prng->bytes($length); |
258 | 258 | =head2 double |
259 | 259 | |
260 | 260 | $n = $prng->double; |
261 | #or | |
261 | #or | |
262 | 262 | $n = $prng->double($limit); |
263 | 263 | |
264 | 264 | See L<rand|/rand> |
24 | 24 | |
25 | 25 | =item * Ciphers - see L<Crypt::Cipher> and related modules |
26 | 26 | |
27 | L<Crypt::Cipher::AES>, L<Crypt::Cipher::Anubis>, L<Crypt::Cipher::Blowfish>, L<Crypt::Cipher::Camellia>, L<Crypt::Cipher::CAST5>, L<Crypt::Cipher::DES>, | |
28 | L<Crypt::Cipher::DES_EDE>, L<Crypt::Cipher::KASUMI>, L<Crypt::Cipher::Khazad>, L<Crypt::Cipher::MULTI2>, L<Crypt::Cipher::Noekeon>, L<Crypt::Cipher::RC2>, | |
29 | L<Crypt::Cipher::RC5>, L<Crypt::Cipher::RC6>, L<Crypt::Cipher::SAFERP>, L<Crypt::Cipher::SAFER_K128>, L<Crypt::Cipher::SAFER_K64>, L<Crypt::Cipher::SAFER_SK128>, | |
27 | L<Crypt::Cipher::AES>, L<Crypt::Cipher::Anubis>, L<Crypt::Cipher::Blowfish>, L<Crypt::Cipher::Camellia>, L<Crypt::Cipher::CAST5>, L<Crypt::Cipher::DES>, | |
28 | L<Crypt::Cipher::DES_EDE>, L<Crypt::Cipher::KASUMI>, L<Crypt::Cipher::Khazad>, L<Crypt::Cipher::MULTI2>, L<Crypt::Cipher::Noekeon>, L<Crypt::Cipher::RC2>, | |
29 | L<Crypt::Cipher::RC5>, L<Crypt::Cipher::RC6>, L<Crypt::Cipher::SAFERP>, L<Crypt::Cipher::SAFER_K128>, L<Crypt::Cipher::SAFER_K64>, L<Crypt::Cipher::SAFER_SK128>, | |
30 | 30 | L<Crypt::Cipher::SAFER_SK64>, L<Crypt::Cipher::SEED>, L<Crypt::Cipher::Skipjack>, L<Crypt::Cipher::Twofish>, L<Crypt::Cipher::XTEA> |
31 | 31 | |
32 | 32 | =item * Block cipher modes |
39 | 39 | |
40 | 40 | =item * Hash Functions - see L<Crypt::Digest> and related modules |
41 | 41 | |
42 | L<Crypt::Digest::CHAES>, L<Crypt::Digest::MD2>, L<Crypt::Digest::MD4>, L<Crypt::Digest::MD5>, L<Crypt::Digest::RIPEMD128>, L<Crypt::Digest::RIPEMD160>, | |
43 | L<Crypt::Digest::RIPEMD256>, L<Crypt::Digest::RIPEMD320>, L<Crypt::Digest::SHA1>, L<Crypt::Digest::SHA224>, L<Crypt::Digest::SHA256>, L<Crypt::Digest::SHA384>, | |
42 | L<Crypt::Digest::CHAES>, L<Crypt::Digest::MD2>, L<Crypt::Digest::MD4>, L<Crypt::Digest::MD5>, L<Crypt::Digest::RIPEMD128>, L<Crypt::Digest::RIPEMD160>, | |
43 | L<Crypt::Digest::RIPEMD256>, L<Crypt::Digest::RIPEMD320>, L<Crypt::Digest::SHA1>, L<Crypt::Digest::SHA224>, L<Crypt::Digest::SHA256>, L<Crypt::Digest::SHA384>, | |
44 | 44 | L<Crypt::Digest::SHA512>, L<Crypt::Digest::Tiger192>, L<Crypt::Digest::Whirlpool> |
45 | 45 | |
46 | 46 | =item * Message Authentication Codes |
205 | 205 | if(register_hash(&sha384_desc)==-1) { croak("FATAL: cannot register_hash sha384"); } |
206 | 206 | if(register_hash(&sha512_desc)==-1) { croak("FATAL: cannot register_hash sha512"); } |
207 | 207 | if(register_hash(&tiger_desc)==-1) { croak("FATAL: cannot register_hash tiger"); } |
208 | if(register_hash(&whirlpool_desc)==-1) { croak("FATAL: cannot register_hash whirlpool"); } | |
208 | if(register_hash(&whirlpool_desc)==-1) { croak("FATAL: cannot register_hash whirlpool"); } | |
209 | 209 | /* --- */ |
210 | 210 | if(chc_register(find_cipher("aes"))==-1) { croak("FATAL: chc_register failed"); } |
211 | 211 | /* --- */ |
244 | 244 | INCLUDE: CryptX_Mac_Pelican.xs.inc |
245 | 245 | INCLUDE: CryptX_Mac_PMAC.xs.inc |
246 | 246 | INCLUDE: CryptX_Mac_XCBC.xs.inc |
247 | ||
247 | ||
248 | 248 | INCLUDE: CryptX_Mode_CBC.xs.inc |
249 | 249 | INCLUDE: CryptX_Mode_ECB.xs.inc |
250 | 250 | INCLUDE: CryptX_Mode_CFB.xs.inc |
8 | 8 | int rv, id; |
9 | 9 | unsigned char tag[MAXBLOCKSIZE]; |
10 | 10 | SV *ct; |
11 | ||
11 | ||
12 | 12 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 13 | if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); |
14 | 14 | if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar"); |
15 | 15 | if (!SvPOK(plaintext)) croak("FATAL: plaintext must be string/buffer scalar"); |
16 | 16 | k = (unsigned char *) SvPVbyte(key, k_len); |
17 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
17 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
18 | 18 | h = (unsigned char *) SvPVbyte(header, h_len); |
19 | 19 | pt = (unsigned char *) SvPVbyte(plaintext, pt_len); |
20 | 20 | |
21 | 21 | id = find_cipher(cipher_name); |
22 | 22 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
23 | ||
23 | ||
24 | 24 | ct = NEWSV(0, pt_len); |
25 | 25 | SvPOK_only(ct); |
26 | 26 | SvCUR_set(ct, pt_len); |
27 | ||
27 | ||
28 | 28 | if(tag_len<4 || tag_len>16) tag_len = 16; |
29 | ||
29 | ||
30 | 30 | rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, |
31 | 31 | pt, (unsigned long)pt_len, (unsigned char *)SvPV_nolen(ct), tag, &tag_len, CCM_ENCRYPT); |
32 | 32 | if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); |
33 | ||
33 | ||
34 | 34 | XPUSHs(sv_2mortal(ct)); |
35 | 35 | XPUSHs(sv_2mortal(newSVpvn((char*)tag,tag_len))); |
36 | 36 | |
43 | 43 | unsigned char *ct, |
44 | 44 | unsigned char *tag, unsigned long *taglen, |
45 | 45 | int direction); */ |
46 | ||
46 | ||
47 | 47 | } |
48 | 48 | |
49 | 49 | void |
54 | 54 | unsigned char *k, *n, *h, *ct, *t; |
55 | 55 | int rv, id; |
56 | 56 | unsigned char xtag[MAXBLOCKSIZE]; |
57 | unsigned long xtag_len; | |
57 | unsigned long xtag_len; | |
58 | 58 | SV *pt; |
59 | ||
59 | ||
60 | 60 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
61 | 61 | if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); |
62 | 62 | if (!SvPOK(header)) croak("FATAL: header must be string/buffer scalar"); |
63 | 63 | if (!SvPOK(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar"); |
64 | 64 | if (!SvPOK(tag)) croak("FATAL: tag must be string/buffer scalar"); |
65 | 65 | k = (unsigned char *) SvPVbyte(key, k_len); |
66 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
66 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
67 | 67 | h = (unsigned char *) SvPVbyte(header, h_len); |
68 | 68 | ct = (unsigned char *) SvPVbyte(ciphertext, ct_len); |
69 | 69 | t = (unsigned char *) SvPVbyte(tag, t_len); |
70 | 70 | |
71 | 71 | id = find_cipher(cipher_name); |
72 | 72 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
73 | ||
73 | ||
74 | 74 | pt = NEWSV(0, ct_len); |
75 | 75 | SvPOK_only(pt); |
76 | 76 | SvCUR_set(pt, ct_len); |
77 | ||
77 | ||
78 | 78 | xtag_len = (unsigned long)t_len; |
79 | ||
79 | ||
80 | 80 | rv = ccm_memory(id, k, (unsigned long)k_len, NULL, n, (unsigned long)n_len, h, (unsigned long)h_len, |
81 | 81 | (unsigned char *)SvPV_nolen(pt), (unsigned long)ct_len, ct, xtag, &xtag_len, CCM_DECRYPT); |
82 | 82 | if (rv != CRYPT_OK) croak("FATAL: ccm_memory failed: %s", error_to_string(rv)); |
83 | ||
83 | ||
84 | 84 | if (t_len!=xtag_len) { |
85 | 85 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ |
86 | 86 | } |
87 | 87 | else if (memNE(t, xtag, xtag_len)) { |
88 | 88 | XPUSHs(sv_2mortal(newSVpvn(NULL,0))); /* undef */ |
89 | 89 | } |
90 | else { | |
90 | else { | |
91 | 91 | XPUSHs(sv_2mortal(pt)); |
92 | 92 | } |
93 | 93 | } |
10 | 10 | unsigned char *h=NULL; |
11 | 11 | STRLEN h_len=0; |
12 | 12 | int id; |
13 | ||
13 | ||
14 | 14 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
15 | 15 | k = (unsigned char *) SvPVbyte(key, k_len); |
16 | 16 | if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); |
17 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
17 | n = (unsigned char *) SvPVbyte(nonce, n_len); | |
18 | 18 | if(SvOK(header)) { /* header is optional param */ |
19 | 19 | if(!SvPOK(header)) croak("FATAL: header must be string/buffer scalar"); |
20 | 20 | h = (unsigned char *) SvPVbyte(header, h_len); |
65 | 65 | SvCUR_set(RETVAL, in_data_len); |
66 | 66 | out_data = (unsigned char *)SvPV_nolen(RETVAL); |
67 | 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)); | |
68 | if (rv != CRYPT_OK) croak("FATAL: eax_encrypt failed: %s", error_to_string(rv)); | |
69 | 69 | } |
70 | 70 | } |
71 | 71 | OUTPUT: |
78 | 78 | int rv; |
79 | 79 | STRLEN in_data_len; |
80 | 80 | unsigned char *in_data, *out_data; |
81 | ||
82 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
81 | ||
82 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
83 | 83 | if (in_data_len==0) { |
84 | 84 | RETVAL = newSVpvn("", 0); |
85 | 85 | } |
89 | 89 | SvCUR_set(RETVAL, in_data_len); |
90 | 90 | out_data = (unsigned char *)SvPV_nolen(RETVAL); |
91 | 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)); | |
92 | if (rv != CRYPT_OK) croak("FATAL: eax_decrypt failed: %s", error_to_string(rv)); | |
93 | 93 | } |
94 | 94 | } |
95 | 95 | OUTPUT: |
102 | 102 | int rv; |
103 | 103 | unsigned char tag[MAXBLOCKSIZE]; |
104 | 104 | unsigned long tag_len = sizeof(tag); |
105 | ||
105 | ||
106 | 106 | rv = eax_done(&self->state, tag, &tag_len); |
107 | 107 | if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); |
108 | 108 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); |
117 | 117 | unsigned long tag_len = sizeof(tag); |
118 | 118 | STRLEN expected_tag_len; |
119 | 119 | unsigned char *expected_tag; |
120 | ||
120 | ||
121 | 121 | rv = eax_done(&self->state, tag, &tag_len); |
122 | 122 | if (rv != CRYPT_OK) croak("FATAL: eax_done failed: %s", error_to_string(rv)); |
123 | 123 | if (items == 1) { |
134 | 134 | } |
135 | 135 | else { |
136 | 136 | XPUSHs(sv_2mortal(newSViv(1))); /* true */ |
137 | } | |
137 | } | |
138 | 138 | } |
139 | 139 | } |
140 | 140 |
6 | 6 | STRLEN k_len=0; |
7 | 7 | unsigned char *k=NULL; |
8 | 8 | int id; |
9 | ||
9 | ||
10 | 10 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
11 | 11 | k = (unsigned char *) SvPVbyte(key, k_len); |
12 | 12 | |
44 | 44 | { |
45 | 45 | int rv; |
46 | 46 | rv = gcm_reset(&self->state); |
47 | if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv)); | |
47 | if (rv != CRYPT_OK) croak("FATAL: gcm_reset failed: %s", error_to_string(rv)); | |
48 | 48 | RETVAL = rv; |
49 | 49 | } |
50 | 50 | OUTPUT: |
62 | 62 | if (in_data_len==0) { |
63 | 63 | RETVAL = newSVpvn("", 0); |
64 | 64 | } |
65 | else | |
65 | else | |
66 | 66 | { |
67 | 67 | RETVAL = NEWSV(0, in_data_len); |
68 | 68 | SvPOK_only(RETVAL); |
69 | 69 | SvCUR_set(RETVAL, in_data_len); |
70 | 70 | out_data = (unsigned char *)SvPV_nolen(RETVAL); |
71 | 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)); | |
72 | if (rv != CRYPT_OK) croak("FATAL: encrypt_add/gcm_process failed: %s", error_to_string(rv)); | |
73 | 73 | } |
74 | 74 | } |
75 | 75 | OUTPUT: |
85 | 85 | |
86 | 86 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); |
87 | 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)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: gcm_add_iv failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = rv; |
90 | 90 | } |
91 | 91 | OUTPUT: |
101 | 101 | |
102 | 102 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); |
103 | 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)); | |
104 | if (rv != CRYPT_OK) croak("FATAL: gcm_add_aad failed: %s", error_to_string(rv)); | |
105 | 105 | RETVAL = rv; |
106 | 106 | } |
107 | 107 | OUTPUT: |
114 | 114 | int rv; |
115 | 115 | STRLEN in_data_len; |
116 | 116 | unsigned char *in_data, *out_data; |
117 | ||
118 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
117 | ||
118 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
119 | 119 | if (in_data_len==0) { |
120 | 120 | RETVAL = newSVpvn("", 0); |
121 | 121 | } |
139 | 139 | int rv; |
140 | 140 | unsigned char tag[MAXBLOCKSIZE]; |
141 | 141 | unsigned long tag_len = sizeof(tag); |
142 | ||
142 | ||
143 | 143 | rv = gcm_done(&self->state, tag, &tag_len); |
144 | 144 | if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); |
145 | 145 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); |
154 | 154 | unsigned long tag_len = sizeof(tag); |
155 | 155 | STRLEN expected_tag_len; |
156 | 156 | unsigned char *expected_tag; |
157 | ||
157 | ||
158 | 158 | rv = gcm_done(&self->state, tag, &tag_len); |
159 | 159 | if (rv != CRYPT_OK) croak("FATAL: gcm_done failed: %s", error_to_string(rv)); |
160 | 160 | if (items == 1) { |
171 | 171 | } |
172 | 172 | else { |
173 | 173 | XPUSHs(sv_2mortal(newSViv(1))); /* true */ |
174 | } | |
174 | } | |
175 | 175 | } |
176 | 176 | } |
8 | 8 | unsigned char *n=NULL; |
9 | 9 | STRLEN n_len=0; |
10 | 10 | int id; |
11 | ||
11 | ||
12 | 12 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 13 | k = (unsigned char *) SvPVbyte(key, k_len); |
14 | 14 | if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); |
53 | 53 | |
54 | 54 | if (in_data_len>0) { |
55 | 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)); | |
56 | if (rv != CRYPT_OK) croak("FATAL: ocb3_add_aad failed: %s", error_to_string(rv)); | |
57 | 57 | } |
58 | 58 | } |
59 | 59 | |
79 | 79 | croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len); |
80 | 80 | |
81 | 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)); | |
82 | if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt failed: %s", error_to_string(rv)); | |
83 | 83 | } |
84 | 84 | } |
85 | 85 | OUTPUT: |
93 | 93 | STRLEN in_data_len; |
94 | 94 | unsigned char *in_data, *out_data; |
95 | 95 | |
96 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
96 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
97 | 97 | if (in_data_len>0) { |
98 | 98 | RETVAL = NEWSV(0, in_data_len); |
99 | 99 | SvPOK_only(RETVAL); |
105 | 105 | out_data = NULL; |
106 | 106 | } |
107 | 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)); | |
108 | if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); | |
109 | 109 | } |
110 | 110 | OUTPUT: |
111 | 111 | RETVAL |
117 | 117 | int rv; |
118 | 118 | STRLEN in_data_len; |
119 | 119 | unsigned char *in_data, *out_data; |
120 | ||
121 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
120 | ||
121 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
122 | 122 | if (in_data_len==0) { |
123 | 123 | RETVAL = newSVpvn("", 0); |
124 | 124 | } |
132 | 132 | croak ("FATAL: sizeof(data) should be multiple of blocksize (%d)", (&self->state)->block_len); |
133 | 133 | |
134 | 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)); | |
135 | if (rv != CRYPT_OK) croak("FATAL: ocb3_decrypt failed: %s", error_to_string(rv)); | |
136 | 136 | } |
137 | 137 | } |
138 | 138 | OUTPUT: |
146 | 146 | STRLEN in_data_len; |
147 | 147 | unsigned char *in_data, *out_data; |
148 | 148 | |
149 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
149 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
150 | 150 | if (in_data_len>0) { |
151 | 151 | RETVAL = NEWSV(0, in_data_len); |
152 | 152 | SvPOK_only(RETVAL); |
158 | 158 | out_data = NULL; |
159 | 159 | } |
160 | 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)); | |
161 | if (rv != CRYPT_OK) croak("FATAL: ocb3_encrypt_last failed: %s", error_to_string(rv)); | |
162 | 162 | } |
163 | 163 | OUTPUT: |
164 | 164 | RETVAL |
170 | 170 | int rv; |
171 | 171 | unsigned char tag[MAXBLOCKSIZE]; |
172 | 172 | unsigned long tag_len = sizeof(tag); |
173 | ||
173 | ||
174 | 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)); | |
175 | if (rv != CRYPT_OK) croak("FATAL: ocb3_done_encrypt failed: %s", error_to_string(rv)); | |
176 | 176 | |
177 | 177 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); |
178 | 178 | } |
186 | 186 | unsigned long tag_len = sizeof(tag); |
187 | 187 | STRLEN expected_tag_len; |
188 | 188 | unsigned char *expected_tag; |
189 | ||
190 | rv = ocb3_done(&self->state, tag, &tag_len); | |
189 | ||
190 | rv = ocb3_done(&self->state, tag, &tag_len); | |
191 | 191 | if (rv != CRYPT_OK) croak("FATAL: ocb3_done_decrypt failed: %s", error_to_string(rv)); |
192 | 192 | if (items == 1) { |
193 | 193 | XPUSHs(sv_2mortal(newSVpvn((char*)tag, tag_len))); |
203 | 203 | } |
204 | 204 | else { |
205 | 205 | XPUSHs(sv_2mortal(newSViv(1))); /* true */ |
206 | } | |
206 | } | |
207 | 207 | } |
208 | 208 | } |
209 | 209 |
10 | 10 | unsigned char *key_data=NULL; |
11 | 11 | int rv; |
12 | 12 | int id; |
13 | ||
13 | ||
14 | 14 | if (!SvPOK (key)) croak("FATAL: key must be string scalar"); |
15 | 15 | key_data = (unsigned char *)SvPVbyte(key, key_len); |
16 | ||
16 | ||
17 | 17 | id = find_cipher(cipher_name); |
18 | 18 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
19 | 19 | |
124 | 124 | CODE: |
125 | 125 | { |
126 | 126 | int rv, id; |
127 | ||
127 | ||
128 | 128 | id = find_cipher(cipher_name); |
129 | 129 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
130 | ||
130 | ||
131 | 131 | rv = cipher_descriptor[id].block_length; |
132 | 132 | if (!rv) XSRETURN_UNDEF; |
133 | 133 | RETVAL = rv; |
141 | 141 | CODE: |
142 | 142 | { |
143 | 143 | int rv, id; |
144 | ||
144 | ||
145 | 145 | id = find_cipher(cipher_name); |
146 | 146 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
147 | ||
147 | ||
148 | 148 | rv = cipher_descriptor[id].min_key_length; |
149 | 149 | if (!rv) XSRETURN_UNDEF; |
150 | 150 | RETVAL = rv; |
158 | 158 | CODE: |
159 | 159 | { |
160 | 160 | int rv, id; |
161 | ||
161 | ||
162 | 162 | id = find_cipher(cipher_name); |
163 | 163 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
164 | ||
164 | ||
165 | 165 | rv = cipher_descriptor[id].max_key_length; |
166 | 166 | if (!rv) XSRETURN_UNDEF; |
167 | 167 | RETVAL = rv; |
175 | 175 | CODE: |
176 | 176 | { |
177 | 177 | int rv, id; |
178 | ||
178 | ||
179 | 179 | id = find_cipher(cipher_name); |
180 | 180 | if(id==-1) croak("FATAL: find_cipfer failed for '%s'", cipher_name); |
181 | ||
181 | ||
182 | 182 | rv = cipher_descriptor[id].default_rounds; |
183 | 183 | if (!rv) XSRETURN_UNDEF; |
184 | 184 | RETVAL = rv; |
53 | 53 | STRLEN inlen; |
54 | 54 | int rv, i; |
55 | 55 | unsigned char *in; |
56 | ||
56 | ||
57 | 57 | for(i=1; i<items; i++) { |
58 | 58 | in = (unsigned char *)SvPVbyte(ST(i), inlen); |
59 | 59 | if (inlen>0) { |
71 | 71 | { |
72 | 72 | unsigned char hash[MAXBLOCKSIZE]; |
73 | 73 | int rv; |
74 | ||
74 | ||
75 | 75 | rv = self->desc->done(&self->state, hash); |
76 | 76 | if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); |
77 | 77 | RETVAL = newSVpvn((char *) hash, self->desc->hashsize); |
88 | 88 | unsigned long i; |
89 | 89 | unsigned char hash[MAXBLOCKSIZE]; |
90 | 90 | char hash_hex[MAXBLOCKSIZE*2 + 1]; |
91 | ||
91 | ||
92 | 92 | rv = self->desc->done(&self->state, hash); |
93 | 93 | if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); |
94 | ||
94 | ||
95 | 95 | hash_hex[0] = '\0'; |
96 | 96 | for(i=0; i<self->desc->hashsize; i++) |
97 | 97 | sprintf(&hash_hex[2*i], "%02x", hash[i]); |
109 | 109 | unsigned long outlen; |
110 | 110 | unsigned char hash[MAXBLOCKSIZE]; |
111 | 111 | char hash_base64[MAXBLOCKSIZE*2 + 1]; |
112 | ||
112 | ||
113 | 113 | rv = self->desc->done(&self->state, hash); |
114 | 114 | if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); |
115 | ||
115 | ||
116 | 116 | outlen = sizeof(hash_base64); |
117 | 117 | rv = base64_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); |
118 | 118 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); |
130 | 130 | unsigned long outlen; |
131 | 131 | unsigned char hash[MAXBLOCKSIZE]; |
132 | 132 | char hash_base64[MAXBLOCKSIZE*2 + 1]; |
133 | ||
133 | ||
134 | 134 | rv = self->desc->done(&self->state, hash); |
135 | 135 | if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv)); |
136 | ||
136 | ||
137 | 137 | outlen = sizeof(hash_base64); |
138 | 138 | rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen); |
139 | 139 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); |
156 | 156 | CODE: |
157 | 157 | { |
158 | 158 | int rv, id; |
159 | ||
159 | ||
160 | 160 | id = find_hash(digest_name); |
161 | 161 | if(id==-1) croak("FATAL: find_digest failed for '%s'", digest_name); |
162 | ||
162 | ||
163 | 163 | rv = hash_descriptor[id].hashsize; |
164 | 164 | if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);; |
165 | 165 | RETVAL = rv; |
4 | 4 | CODE: |
5 | 5 | { |
6 | 6 | /* |
7 | int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, | |
8 | const unsigned char *salt, | |
7 | int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, | |
8 | const unsigned char *salt, | |
9 | 9 | int iteration_count, int hash_idx, |
10 | 10 | unsigned char *out, unsigned long *outlen) |
11 | 11 | */ |
19 | 19 | |
20 | 20 | id = find_hash(hash_name); |
21 | 21 | if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
22 | ||
22 | ||
23 | 23 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); |
24 | 24 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); |
25 | 25 | if (salt_len < 8) croak("FATAL: salt_len has to be 8"); |
26 | ||
26 | ||
27 | 27 | output_len = len; |
28 | 28 | Newz(0, output, output_len, unsigned char); |
29 | 29 | if (!output) croak("FATAL: Newz failed [%ld]", output_len); |
30 | ||
30 | ||
31 | 31 | rv = pkcs_5_alg1(password_ptr, (unsigned long)password_len, salt_ptr, iteration_count, id, output, &output_len); |
32 | 32 | if (rv != CRYPT_OK) croak("FATAL: pkcs_5_alg1 process failed: %s", error_to_string(rv)); |
33 | ||
33 | ||
34 | 34 | RETVAL = newSVpvn((char *)output, output_len); |
35 | 35 | Safefree(output); |
36 | 36 | } |
42 | 42 | CODE: |
43 | 43 | { |
44 | 44 | /* |
45 | int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, | |
45 | int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, | |
46 | 46 | const unsigned char *salt, unsigned long salt_len, |
47 | 47 | int iteration_count, int hash_idx, |
48 | 48 | unsigned char *out, unsigned long *outlen) |
57 | 57 | |
58 | 58 | id = find_hash(hash_name); |
59 | 59 | if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
60 | ||
60 | ||
61 | 61 | password_ptr = (unsigned char *)SvPVbyte(password, password_len); |
62 | 62 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); |
63 | ||
63 | ||
64 | 64 | output_len = len; |
65 | 65 | Newz(0, output, output_len, unsigned char); |
66 | 66 | if (!output) croak("FATAL: Newz failed [%ld]", output_len); |
67 | ||
67 | ||
68 | 68 | rv = pkcs_5_alg2(password_ptr, (unsigned long)password_len, salt_ptr, (unsigned long)salt_len, iteration_count, id, output, &output_len); |
69 | 69 | if (rv != CRYPT_OK) croak("FATAL: pkcs_5_alg2 process failed: %s", error_to_string(rv)); |
70 | ||
70 | ||
71 | 71 | RETVAL = newSVpvn((char *)output, output_len); |
72 | 72 | Safefree(output); |
73 | 73 | } |
93 | 93 | |
94 | 94 | id = find_hash(hash_name); |
95 | 95 | if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
96 | ||
96 | ||
97 | 97 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); |
98 | 98 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); |
99 | ||
99 | ||
100 | 100 | output_len = sizeof(output); |
101 | 101 | rv = hkdf_extract(id, salt_ptr, (unsigned long)salt_len, in_ptr, (unsigned long)in_len, output, &output_len); |
102 | 102 | if (rv != CRYPT_OK) croak("FATAL: hkdf_extract process failed: %s", error_to_string(rv)); |
103 | ||
103 | ||
104 | 104 | RETVAL = newSVpvn((char *)output, output_len); |
105 | 105 | } |
106 | 106 | OUTPUT: |
124 | 124 | |
125 | 125 | id = find_hash(hash_name); |
126 | 126 | if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
127 | ||
127 | ||
128 | 128 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); |
129 | 129 | info_ptr = (unsigned char *)SvPVbyte(info, info_len); |
130 | ||
130 | ||
131 | 131 | Newz(0, output, output_len, unsigned char); |
132 | 132 | if (!output) croak("FATAL: Newz failed [%ld]", output_len); |
133 | ||
133 | ||
134 | 134 | rv = hkdf_expand(id, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); |
135 | 135 | if (rv != CRYPT_OK) croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); |
136 | ||
136 | ||
137 | 137 | RETVAL = newSVpvn((char *)output, output_len); |
138 | 138 | Safefree(output); |
139 | 139 | } |
161 | 161 | |
162 | 162 | id = find_hash(hash_name); |
163 | 163 | if(id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
164 | ||
164 | ||
165 | 165 | in_ptr = (unsigned char *)SvPVbyte(in, in_len); |
166 | 166 | info_ptr = (unsigned char *)SvPVbyte(info, info_len); |
167 | 167 | salt_ptr = (unsigned char *)SvPVbyte(salt, salt_len); |
168 | ||
168 | ||
169 | 169 | Newz(0, output, output_len, unsigned char); |
170 | 170 | if (!output) croak("FATAL: Newz failed [%ld]", output_len); |
171 | ||
171 | ||
172 | 172 | rv = hkdf(id, salt_ptr, (unsigned long)salt_len, info_ptr, (unsigned long)info_len, in_ptr, (unsigned long)in_len, output, output_len); |
173 | 173 | if (rv != CRYPT_OK) croak("FATAL: hkdf_expand process failed: %s", error_to_string(rv)); |
174 | ||
174 | ||
175 | 175 | RETVAL = newSVpvn((char *)output, output_len); |
176 | 176 | Safefree(output); |
177 | 177 | } |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | int id; |
12 | 12 | |
13 | 13 | id = find_cipher(cipher_name); |
47 | 47 | STRLEN in_data_len; |
48 | 48 | unsigned char *in_data; |
49 | 49 | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
51 | 51 | if (in_data_len>0) { |
52 | 52 | rv = f9_process(&self->state, in_data, (unsigned long)in_data_len); |
53 | 53 | if (rv != CRYPT_OK) croak("FATAL: f9_process failed: %s", error_to_string(rv)); |
85 | 85 | if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); |
86 | 86 | outlen = sizeof(mac_base64); |
87 | 87 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = newSVpvn(mac_base64, outlen); |
90 | 90 | } |
91 | 91 | OUTPUT: |
106 | 106 | if (rv != CRYPT_OK) croak("FATAL: f9_done failed: %s", error_to_string(rv)); |
107 | 107 | outlen = sizeof(mac_base64); |
108 | 108 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
110 | 110 | RETVAL = newSVpvn(mac_base64, outlen); |
111 | 111 | } |
112 | 112 | OUTPUT: |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | int id; |
12 | 12 | |
13 | 13 | id = find_hash(hash_name); |
47 | 47 | STRLEN in_data_len; |
48 | 48 | unsigned char *in_data; |
49 | 49 | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
51 | 51 | if (in_data_len>0) { |
52 | 52 | rv = hmac_process(&self->state, in_data, (unsigned long)in_data_len); |
53 | 53 | if (rv != CRYPT_OK) croak("FATAL: hmac_process failed: %s", error_to_string(rv)); |
85 | 85 | if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); |
86 | 86 | outlen = sizeof(mac_base64); |
87 | 87 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = newSVpvn(mac_base64, outlen); |
90 | 90 | } |
91 | 91 | OUTPUT: |
106 | 106 | if (rv != CRYPT_OK) croak("FATAL: hmac_done failed: %s", error_to_string(rv)); |
107 | 107 | outlen = sizeof(mac_base64); |
108 | 108 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
110 | 110 | RETVAL = newSVpvn(mac_base64, outlen); |
111 | 111 | } |
112 | 112 | OUTPUT: |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | int id; |
12 | 12 | |
13 | 13 | id = find_cipher(cipher_name); |
47 | 47 | STRLEN in_data_len; |
48 | 48 | unsigned char *in_data; |
49 | 49 | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
51 | 51 | if (in_data_len>0) { |
52 | 52 | rv = omac_process(&self->state, in_data, (unsigned long)in_data_len); |
53 | 53 | if (rv != CRYPT_OK) croak("FATAL: omac_process failed: %s", error_to_string(rv)); |
85 | 85 | if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); |
86 | 86 | outlen = sizeof(mac_base64); |
87 | 87 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = newSVpvn(mac_base64, outlen); |
90 | 90 | } |
91 | 91 | OUTPUT: |
106 | 106 | if (rv != CRYPT_OK) croak("FATAL: omac_done failed: %s", error_to_string(rv)); |
107 | 107 | outlen = sizeof(mac_base64); |
108 | 108 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
110 | 110 | RETVAL = newSVpvn(mac_base64, outlen); |
111 | 111 | } |
112 | 112 | OUTPUT: |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | int id; |
12 | 12 | |
13 | 13 | id = find_cipher(cipher_name); |
47 | 47 | STRLEN in_data_len; |
48 | 48 | unsigned char *in_data; |
49 | 49 | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
51 | 51 | if (in_data_len>0) { |
52 | 52 | rv = pmac_process(&self->state, in_data, (unsigned long)in_data_len); |
53 | 53 | if (rv != CRYPT_OK) croak("FATAL: pmac_process failed: %s", error_to_string(rv)); |
85 | 85 | if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); |
86 | 86 | outlen = sizeof(mac_base64); |
87 | 87 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = newSVpvn(mac_base64, outlen); |
90 | 90 | } |
91 | 91 | OUTPUT: |
106 | 106 | if (rv != CRYPT_OK) croak("FATAL: pmac_done failed: %s", error_to_string(rv)); |
107 | 107 | outlen = sizeof(mac_base64); |
108 | 108 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
110 | 110 | RETVAL = newSVpvn(mac_base64, outlen); |
111 | 111 | } |
112 | 112 | OUTPUT: |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | |
12 | 12 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); |
13 | 13 | k = (unsigned char *) SvPVbyte(key, k_len); |
15 | 15 | Newz(0, RETVAL, 1, struct pelican_struct); |
16 | 16 | if (!RETVAL) croak("FATAL: Newz failed"); |
17 | 17 | |
18 | rv = pelican_init(&RETVAL->state, k, (unsigned long)k_len); | |
18 | rv = pelican_init(&RETVAL->state, k, (unsigned long)k_len); | |
19 | 19 | if (rv != CRYPT_OK) croak("FATAL: pelican_init failed: %s", error_to_string(rv)); |
20 | 20 | } |
21 | 21 | OUTPUT: |
43 | 43 | STRLEN in_data_len; |
44 | 44 | unsigned char *in_data; |
45 | 45 | |
46 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
46 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
47 | 47 | if (in_data_len>0) { |
48 | 48 | rv = pelican_process(&self->state, in_data, (unsigned long)in_data_len); |
49 | 49 | if (rv != CRYPT_OK) croak("FATAL: pelican_process failed: %s", error_to_string(rv)); |
81 | 81 | if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); |
82 | 82 | outlen = sizeof(mac_base64); |
83 | 83 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
84 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
84 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
85 | 85 | RETVAL = newSVpvn(mac_base64, outlen); |
86 | 86 | } |
87 | 87 | OUTPUT: |
102 | 102 | if (rv != CRYPT_OK) croak("FATAL: pelican_done failed: %s", error_to_string(rv)); |
103 | 103 | outlen = sizeof(mac_base64); |
104 | 104 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
105 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
105 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
106 | 106 | RETVAL = newSVpvn(mac_base64, outlen); |
107 | 107 | } |
108 | 108 | OUTPUT: |
7 | 7 | { |
8 | 8 | STRLEN k_len=0; |
9 | 9 | unsigned char *k=NULL; |
10 | int rv; | |
10 | int rv; | |
11 | 11 | int id; |
12 | 12 | |
13 | 13 | id = find_cipher(cipher_name); |
47 | 47 | STRLEN in_data_len; |
48 | 48 | unsigned char *in_data; |
49 | 49 | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
50 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
51 | 51 | if (in_data_len>0) { |
52 | 52 | rv = xcbc_process(&self->state, in_data, (unsigned long)in_data_len); |
53 | 53 | if (rv != CRYPT_OK) croak("FATAL: xcbc_process failed: %s", error_to_string(rv)); |
85 | 85 | if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); |
86 | 86 | outlen = sizeof(mac_base64); |
87 | 87 | rv = base64_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
88 | if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv)); | |
89 | 89 | RETVAL = newSVpvn(mac_base64, outlen); |
90 | 90 | } |
91 | 91 | OUTPUT: |
106 | 106 | if (rv != CRYPT_OK) croak("FATAL: xcbc_done failed: %s", error_to_string(rv)); |
107 | 107 | outlen = sizeof(mac_base64); |
108 | 108 | rv = base64url_encode(mac, mac_len, (unsigned char*)mac_base64, &outlen); |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
109 | if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv)); | |
110 | 110 | RETVAL = newSVpvn(mac_base64, outlen); |
111 | 111 | } |
112 | 112 | OUTPUT: |
93 | 93 | in_data_len = 0; |
94 | 94 | } |
95 | 95 | } /* padlen > 0 */ |
96 | ||
96 | ||
97 | 97 | i = (unsigned long)(in_data_len % blen); |
98 | 98 | if (in_data_len>0 && i>0) { /* save tail of data into pad */ |
99 | 99 | Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); |
100 | 100 | self->padlen = i; |
101 | 101 | in_data_len -= i; |
102 | 102 | } |
103 | ||
103 | ||
104 | 104 | if (in_data_len>0) { |
105 | 105 | i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); |
106 | 106 | RETVAL = NEWSV(0, i); |
107 | 107 | SvPOK_only(RETVAL); |
108 | 108 | SvCUR_set(RETVAL, i); |
109 | 109 | out_data = (unsigned char *)SvPV_nolen(RETVAL); |
110 | ||
110 | ||
111 | 111 | if (has_tmp_block) { |
112 | 112 | Copy(tmp_block, out_data, blen, unsigned char); |
113 | 113 | out_data += blen; |
132 | 132 | { |
133 | 133 | unsigned char tmp_block[MAXBLOCKSIZE]; |
134 | 134 | int rv, blen, i, j; |
135 | ||
135 | ||
136 | 136 | blen = (&self->state)->blocklen; |
137 | 137 | if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); |
138 | ||
138 | ||
139 | 139 | if(self->padding_mode == 1) { /* pkcs5|7 padding */ |
140 | 140 | i = blen - self->padlen; |
141 | 141 | if (i == 0) i = blen; |
147 | 147 | self->pad[self->padlen] = 0x80; |
148 | 148 | for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; |
149 | 149 | rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state); |
150 | if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); | |
150 | if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv)); | |
151 | 151 | } |
152 | 152 | else { |
153 | 153 | if (self->padlen>0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen); |
154 | 154 | blen = 0; |
155 | 155 | } |
156 | ||
156 | ||
157 | 157 | RETVAL = newSVpvn((char*)tmp_block, blen); |
158 | 158 | } |
159 | 159 | OUTPUT: |
178 | 178 | RETVAL = newSVpvn("", 0); |
179 | 179 | } |
180 | 180 | else { |
181 | ||
181 | ||
182 | 182 | if(self->padlen == blen) { |
183 | 183 | rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state); |
184 | 184 | if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv)); |
205 | 205 | in_data_len = 0; |
206 | 206 | } |
207 | 207 | } /* padlen > 0 */ |
208 | ||
208 | ||
209 | 209 | /* here: a/ padlen==1..16 && in_data_len==0; b/ padlen==0 && in_data_len>0 */ |
210 | 210 | if (in_data_len>0) { |
211 | 211 | i = (unsigned long)(in_data_len % blen); |
215 | 215 | in_data_len -= i; |
216 | 216 | } |
217 | 217 | } |
218 | ||
218 | ||
219 | 219 | if (in_data_len>0) { |
220 | 220 | if(self->padlen == 0 && self->padding_mode !=0) { |
221 | 221 | /* in case of padding keep full pad if no more data */ |
256 | 256 | _finish_dec(Crypt::Mode::CBC self) |
257 | 257 | CODE: |
258 | 258 | { |
259 | unsigned char tmp_block[MAXBLOCKSIZE]; | |
259 | unsigned char tmp_block[MAXBLOCKSIZE]; | |
260 | 260 | unsigned char i; |
261 | 261 | int rv, rv_len, blen; |
262 | ||
263 | rv_len = 0; | |
262 | ||
263 | rv_len = 0; | |
264 | 264 | if (self->padlen > 0) { |
265 | 265 | blen = (&self->state)->blocklen; |
266 | 266 | if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); |
86 | 86 | in_data_len = 0; |
87 | 87 | } |
88 | 88 | } /* padlen > 0 */ |
89 | ||
89 | ||
90 | 90 | i = (unsigned long)(in_data_len % blen); |
91 | 91 | if (in_data_len>0 && i>0) { /* save tail of data into pad */ |
92 | 92 | Copy(in_data+in_data_start+in_data_len-i, self->pad, i, unsigned char); |
93 | 93 | self->padlen = i; |
94 | 94 | in_data_len -= i; |
95 | 95 | } |
96 | ||
96 | ||
97 | 97 | if (in_data_len>0) { |
98 | 98 | i = (unsigned long)(has_tmp_block ? in_data_len + blen : in_data_len); |
99 | 99 | RETVAL = NEWSV(0, i); |
100 | 100 | SvPOK_only(RETVAL); |
101 | 101 | SvCUR_set(RETVAL, i); |
102 | 102 | out_data = (unsigned char *)SvPV_nolen(RETVAL); |
103 | ||
103 | ||
104 | 104 | if (has_tmp_block) { |
105 | 105 | Copy(tmp_block, out_data, blen, unsigned char); |
106 | 106 | out_data += blen; |
125 | 125 | { |
126 | 126 | unsigned char tmp_block[MAXBLOCKSIZE]; |
127 | 127 | int rv, blen, i, j; |
128 | ||
128 | ||
129 | 129 | blen = (&self->state)->blocklen; |
130 | 130 | if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen"); |
131 | ||
131 | ||
132 | 132 | if(self->padding_mode == 1) { /* pkcs5|7 padding */ |
133 | 133 | i = blen - self->padlen; |
134 | 134 | if (i == 0) i = blen; |
140 | 140 | self->pad[self->padlen] = 0x80; |
141 | 141 | for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0; |
142 | 142 | rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state); |
143 | if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); | |
143 | if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv)); | |
144 | 144 | } |
145 | 145 | else { |
146 | 146 | if (self->padlen>0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen); |
147 | 147 | blen = 0; |
148 | 148 | } |
149 | ||
149 | ||
150 | 150 | RETVAL = newSVpvn((char*)tmp_block, blen); |
151 | 151 | } |
152 | 152 | OUTPUT: |
171 | 171 | RETVAL = newSVpvn("", 0); |
172 | 172 | } |
173 | 173 | else { |
174 | ||
174 | ||
175 | 175 | if(self->padlen == blen) { |
176 | 176 | rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state); |
177 | 177 | if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv)); |
198 | 198 | in_data_len = 0; |
199 | 199 | } |
200 | 200 | } /* padlen > 0 */ |
201 | ||
201 | ||
202 | 202 | /* here: a/ padlen==1..16 && in_data_len==0; b/ padlen==0 && in_data_len>0 */ |
203 | 203 | if (in_data_len>0) { |
204 | 204 | i = (unsigned long)(in_data_len % blen); |
208 | 208 | in_data_len -= i; |
209 | 209 | } |
210 | 210 | } |
211 | ||
211 | ||
212 | 212 | if (in_data_len>0) { |
213 | 213 | if(self->padlen == 0 && self->padding_mode !=0) { |
214 | 214 | /* in case of padding keep full pad if no more data */ |
249 | 249 | _finish_dec(Crypt::Mode::ECB self) |
250 | 250 | CODE: |
251 | 251 | { |
252 | unsigned char tmp_block[MAXBLOCKSIZE]; | |
252 | unsigned char tmp_block[MAXBLOCKSIZE]; | |
253 | 253 | unsigned char i; |
254 | 254 | int rv, rv_len, blen; |
255 | ||
256 | rv_len = 0; | |
255 | ||
256 | rv_len = 0; | |
257 | 257 | if (self->padlen > 0) { |
258 | 258 | blen = (&self->state)->blocklen; |
259 | 259 | if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen); |
3 | 3 | _new() |
4 | 4 | CODE: |
5 | 5 | { |
6 | int rv; | |
6 | int rv; | |
7 | 7 | Newz(0, RETVAL, 1, struct dh_struct); |
8 | 8 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 9 | RETVAL->key.type = -1; |
34 | 34 | int rv; |
35 | 35 | unsigned char *data=NULL; |
36 | 36 | STRLEN data_len=0; |
37 | ||
37 | ||
38 | 38 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
39 | 39 | dh_free(&self->key); |
40 | 40 | rv = dh_import(data, (unsigned long)data_len, &self->key); |
72 | 72 | /* =====> x */ |
73 | 73 | siz = (self->key.x) ? ltc_mp.unsigned_size(self->key.x) : 0; |
74 | 74 | if (siz>10000) { |
75 | croak("FATAL: key2hash failed - 'x' too big number"); | |
75 | croak("FATAL: key2hash failed - 'x' too big number"); | |
76 | 76 | } |
77 | 77 | if (siz>0) { |
78 | 78 | mp_tohex(self->key.x, buf); |
84 | 84 | /* =====> y */ |
85 | 85 | siz = (self->key.y) ? ltc_mp.unsigned_size(self->key.y) : 0; |
86 | 86 | if (siz>10000) { |
87 | croak("FATAL: key2hash failed - 'y' too big number"); | |
87 | croak("FATAL: key2hash failed - 'y' too big number"); | |
88 | 88 | } |
89 | 89 | if (siz>0) { |
90 | 90 | mp_tohex(self->key.y, buf); |
111 | 111 | int rv; |
112 | 112 | unsigned char out[4096]; |
113 | 113 | unsigned long int out_len = 4096; |
114 | ||
114 | ||
115 | 115 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
116 | 116 | if (strnEQ(type, "private", 7)) { |
117 | 117 | rv = dh_export(out, &out_len, PK_PRIVATE, &self->key); |
139 | 139 | STRLEN data_len=0; |
140 | 140 | unsigned char buffer[1024]; |
141 | 141 | unsigned long buffer_len = 1024; |
142 | ||
143 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
144 | ||
142 | ||
143 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
144 | ||
145 | 145 | hash_id = find_hash(hash_name); |
146 | 146 | if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
147 | 147 | rv = dh_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
162 | 162 | STRLEN data_len=0; |
163 | 163 | unsigned char buffer[1024]; |
164 | 164 | unsigned long buffer_len = 1024; |
165 | ||
165 | ||
166 | 166 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
167 | 167 | |
168 | 168 | rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); |
181 | 181 | STRLEN data_len=0; |
182 | 182 | unsigned char buffer[1024]; |
183 | 183 | unsigned long buffer_len = 1024; |
184 | ||
185 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
186 | ||
184 | ||
185 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
186 | ||
187 | 187 | rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
188 | 188 | &self->yarrow_prng_state, self->yarrow_prng_index, |
189 | 189 | &self->key); |
202 | 202 | STRLEN data_len=0; |
203 | 203 | unsigned char *sig_ptr=NULL; |
204 | 204 | STRLEN sig_len=0; |
205 | ||
205 | ||
206 | 206 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
207 | 207 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
208 | ||
208 | ||
209 | 209 | RETVAL = 1; |
210 | 210 | rv = dh_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); |
211 | 211 | if (rv != CRYPT_OK || stat != 1) RETVAL = 0; |
3 | 3 | _new() |
4 | 4 | CODE: |
5 | 5 | { |
6 | int rv; | |
6 | int rv; | |
7 | 7 | Newz(0, RETVAL, 1, struct dsa_struct); |
8 | 8 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 9 | RETVAL->key.type = -1; |
34 | 34 | int rv; |
35 | 35 | unsigned char *data=NULL; |
36 | 36 | STRLEN data_len=0; |
37 | ||
37 | ||
38 | 38 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
39 | 39 | dsa_free(&self->key); |
40 | 40 | rv = dsa_import(data, (unsigned long)data_len, &self->key); |
80 | 80 | /* =====> g */ |
81 | 81 | siz = (self->key.g) ? ltc_mp.unsigned_size(self->key.g) : 0; |
82 | 82 | if (siz>10000) { |
83 | croak("FATAL: key2hash failed - 'g' too big number"); | |
83 | croak("FATAL: key2hash failed - 'g' too big number"); | |
84 | 84 | } |
85 | 85 | if (siz>0) { |
86 | 86 | mp_tohex(self->key.g, buf); |
92 | 92 | /* =====> q */ |
93 | 93 | siz = (self->key.q) ? ltc_mp.unsigned_size(self->key.q) : 0; |
94 | 94 | if (siz>10000) { |
95 | croak("FATAL: key2hash failed - 'q' too big number"); | |
95 | croak("FATAL: key2hash failed - 'q' too big number"); | |
96 | 96 | } |
97 | 97 | if (siz>0) { |
98 | 98 | mp_tohex(self->key.q, buf); |
104 | 104 | /* =====> p */ |
105 | 105 | siz = (self->key.p) ? ltc_mp.unsigned_size(self->key.p) : 0; |
106 | 106 | if (siz>10000) { |
107 | croak("FATAL: key2hash failed - 'p' too big number"); | |
107 | croak("FATAL: key2hash failed - 'p' too big number"); | |
108 | 108 | } |
109 | 109 | if (siz>0) { |
110 | 110 | mp_tohex(self->key.p, buf); |
116 | 116 | /* =====> x */ |
117 | 117 | siz = (self->key.x) ? ltc_mp.unsigned_size(self->key.x) : 0; |
118 | 118 | if (siz>10000) { |
119 | croak("FATAL: key2hash failed - 'x' too big number"); | |
119 | croak("FATAL: key2hash failed - 'x' too big number"); | |
120 | 120 | } |
121 | 121 | if (siz>0) { |
122 | 122 | mp_tohex(self->key.x, buf); |
128 | 128 | /* =====> y */ |
129 | 129 | siz = (self->key.y) ? ltc_mp.unsigned_size(self->key.y) : 0; |
130 | 130 | if (siz>10000) { |
131 | croak("FATAL: key2hash failed - 'y' too big number"); | |
131 | croak("FATAL: key2hash failed - 'y' too big number"); | |
132 | 132 | } |
133 | 133 | if (siz>0) { |
134 | 134 | mp_tohex(self->key.y, buf); |
152 | 152 | int rv; |
153 | 153 | unsigned char out[4096]; |
154 | 154 | unsigned long int out_len = 4096; |
155 | ||
155 | ||
156 | 156 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
157 | 157 | if (strnEQ(type, "private", 7)) { |
158 | 158 | rv = dsa_export(out, &out_len, PK_PRIVATE, &self->key); |
180 | 180 | STRLEN data_len=0; |
181 | 181 | unsigned char buffer[1024]; |
182 | 182 | unsigned long buffer_len = 1024; |
183 | ||
184 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
185 | ||
183 | ||
184 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
185 | ||
186 | 186 | hash_id = find_hash(hash_name); |
187 | 187 | if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
188 | 188 | rv = dsa_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
203 | 203 | STRLEN data_len=0; |
204 | 204 | unsigned char buffer[1024]; |
205 | 205 | unsigned long buffer_len = 1024; |
206 | ||
206 | ||
207 | 207 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
208 | 208 | |
209 | 209 | rv = dsa_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); |
222 | 222 | STRLEN data_len=0; |
223 | 223 | unsigned char buffer[1024]; |
224 | 224 | unsigned long buffer_len = 1024; |
225 | ||
226 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
227 | ||
225 | ||
226 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); | |
227 | ||
228 | 228 | rv = dsa_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
229 | 229 | &self->yarrow_prng_state, self->yarrow_prng_index, |
230 | 230 | &self->key); |
243 | 243 | STRLEN data_len=0; |
244 | 244 | unsigned char *sig_ptr=NULL; |
245 | 245 | STRLEN sig_len=0; |
246 | ||
246 | ||
247 | 247 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
248 | 248 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
249 | ||
249 | ||
250 | 250 | RETVAL = 1; |
251 | 251 | rv = dsa_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); |
252 | 252 | if (rv != CRYPT_OK || stat != 1) RETVAL = 0; |
3 | 3 | _new() |
4 | 4 | CODE: |
5 | 5 | { |
6 | int rv; | |
6 | int rv; | |
7 | 7 | Newz(0, RETVAL, 1, struct ecc_struct); |
8 | 8 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 9 | RETVAL->key.type = -1; |
34 | 34 | int rv; |
35 | 35 | unsigned char *data=NULL; |
36 | 36 | STRLEN data_len=0; |
37 | ||
37 | ||
38 | 38 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
39 | 39 | ecc_free(&self->key); |
40 | 40 | rv = ecc_import(data, (unsigned long)data_len, &self->key); |
51 | 51 | int rv; |
52 | 52 | unsigned char *data=NULL; |
53 | 53 | STRLEN data_len=0; |
54 | ||
54 | ||
55 | 55 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
56 | 56 | ecc_free(&self->key); |
57 | 57 | rv = ecc_ansi_x963_import(data, (unsigned long)data_len, &self->key); |
89 | 89 | /* =====> k */ |
90 | 90 | siz = (self->key.k) ? ltc_mp.unsigned_size(self->key.k) : 0; |
91 | 91 | if (siz>10000) { |
92 | croak("FATAL: key2hash failed - 'k' too big number"); | |
92 | croak("FATAL: key2hash failed - 'k' too big number"); | |
93 | 93 | } |
94 | 94 | if (siz>0) { |
95 | 95 | mp_tohex(self->key.k, buf); |
101 | 101 | /* =====> pub_x */ |
102 | 102 | siz = (self->key.pubkey.x) ? ltc_mp.unsigned_size(self->key.pubkey.x) : 0; |
103 | 103 | if (siz>10000) { |
104 | croak("FATAL: key2hash failed - 'pub_x' too big number"); | |
104 | croak("FATAL: key2hash failed - 'pub_x' too big number"); | |
105 | 105 | } |
106 | 106 | if (siz>0) { |
107 | 107 | mp_tohex(self->key.pubkey.x, buf); |
113 | 113 | /* =====> pub_y */ |
114 | 114 | siz = (self->key.pubkey.y) ? ltc_mp.unsigned_size(self->key.pubkey.y) : 0; |
115 | 115 | if (siz>10000) { |
116 | croak("FATAL: key2hash failed - 'pub_y' too big number"); | |
116 | croak("FATAL: key2hash failed - 'pub_y' too big number"); | |
117 | 117 | } |
118 | 118 | if (siz>0) { |
119 | 119 | mp_tohex(self->key.pubkey.y, buf); |
125 | 125 | /* =====> pub_z */ |
126 | 126 | siz = (self->key.pubkey.z) ? ltc_mp.unsigned_size(self->key.pubkey.z) : 0; |
127 | 127 | if (siz>10000) { |
128 | croak("FATAL: key2hash failed - 'pub_z' too big number"); | |
128 | croak("FATAL: key2hash failed - 'pub_z' too big number"); | |
129 | 129 | } |
130 | 130 | if (siz>0) { |
131 | 131 | mp_tohex(self->key.pubkey.z, buf); |
159 | 159 | int rv; |
160 | 160 | unsigned char out[4096]; |
161 | 161 | unsigned long int out_len = 4096; |
162 | ||
162 | ||
163 | 163 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
164 | 164 | if (strnEQ(type, "private", 7)) { |
165 | 165 | rv = ecc_export(out, &out_len, PK_PRIVATE, &self->key); |
185 | 185 | int rv; |
186 | 186 | unsigned char out[4096]; |
187 | 187 | unsigned long int out_len = 4096; |
188 | ||
188 | ||
189 | 189 | rv = ecc_ansi_x963_export(&self->key, out, &out_len); |
190 | 190 | if (rv != CRYPT_OK) croak("FATAL: ecc_ansi_x963_export failed: %s", error_to_string(rv)); |
191 | 191 | RETVAL = newSVpvn((char*)out, out_len); |
202 | 202 | STRLEN data_len=0; |
203 | 203 | unsigned char buffer[1024]; |
204 | 204 | unsigned long buffer_len = 1024; |
205 | ||
205 | ||
206 | 206 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
207 | ||
207 | ||
208 | 208 | hash_id = find_hash(hash_name); |
209 | 209 | if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
210 | 210 | rv = ecc_encrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
225 | 225 | STRLEN data_len=0; |
226 | 226 | unsigned char buffer[1024]; |
227 | 227 | unsigned long buffer_len = 1024; |
228 | ||
228 | ||
229 | 229 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
230 | 230 | |
231 | 231 | rv = ecc_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key); |
244 | 244 | STRLEN data_len=0; |
245 | 245 | unsigned char buffer[1024]; |
246 | 246 | unsigned long buffer_len = 1024; |
247 | ||
247 | ||
248 | 248 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
249 | ||
249 | ||
250 | 250 | rv = ecc_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len, |
251 | 251 | &self->yarrow_prng_state, self->yarrow_prng_index, |
252 | 252 | &self->key); |
265 | 265 | STRLEN data_len=0; |
266 | 266 | unsigned char *sig_ptr=NULL; |
267 | 267 | STRLEN sig_len=0; |
268 | ||
268 | ||
269 | 269 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
270 | 270 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
271 | ||
271 | ||
272 | 272 | RETVAL = 1; |
273 | 273 | rv = ecc_verify_hash(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key); |
274 | 274 | if (rv != CRYPT_OK || stat != 1) RETVAL = 0; |
3 | 3 | _new() |
4 | 4 | CODE: |
5 | 5 | { |
6 | int rv; | |
6 | int rv; | |
7 | 7 | Newz(0, RETVAL, 1, struct rsa_struct); |
8 | 8 | if (!RETVAL) croak("FATAL: Newz failed"); |
9 | 9 | RETVAL->key.type = -1; |
35 | 35 | int rv; |
36 | 36 | unsigned char *data=NULL; |
37 | 37 | STRLEN data_len=0; |
38 | ||
38 | ||
39 | 39 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
40 | 40 | rsa_free(&self->key); |
41 | 41 | rv = rsa_import(data, (unsigned long)data_len, &self->key); |
73 | 73 | /* =====> e */ |
74 | 74 | siz = (self->key.e) ? ltc_mp.unsigned_size(self->key.e) : 0; |
75 | 75 | if (siz>10000) { |
76 | croak("FATAL: key2hash failed - 'e' too big number"); | |
76 | croak("FATAL: key2hash failed - 'e' too big number"); | |
77 | 77 | } |
78 | 78 | if (siz>0) { |
79 | 79 | mp_tohex(self->key.e, buf); |
85 | 85 | /* =====> d */ |
86 | 86 | siz = (self->key.d) ? ltc_mp.unsigned_size(self->key.d) : 0; |
87 | 87 | if (siz>10000) { |
88 | croak("FATAL: key2hash failed - 'd' too big number"); | |
88 | croak("FATAL: key2hash failed - 'd' too big number"); | |
89 | 89 | } |
90 | 90 | if (siz>0) { |
91 | 91 | mp_tohex(self->key.d, buf); |
97 | 97 | /* =====> N */ |
98 | 98 | siz = (self->key.N) ? ltc_mp.unsigned_size(self->key.N) : 0; |
99 | 99 | if (siz>10000) { |
100 | croak("FATAL: key2hash failed - 'N' too big number"); | |
100 | croak("FATAL: key2hash failed - 'N' too big number"); | |
101 | 101 | } |
102 | 102 | if (siz>0) { |
103 | 103 | mp_tohex(self->key.N, buf); |
109 | 109 | /* =====> q */ |
110 | 110 | siz = (self->key.q) ? ltc_mp.unsigned_size(self->key.q) : 0; |
111 | 111 | if (siz>10000) { |
112 | croak("FATAL: key2hash failed - 'q' too big number"); | |
112 | croak("FATAL: key2hash failed - 'q' too big number"); | |
113 | 113 | } |
114 | 114 | if (siz>0) { |
115 | 115 | mp_tohex(self->key.q, buf); |
121 | 121 | /* =====> p */ |
122 | 122 | siz = (self->key.p) ? ltc_mp.unsigned_size(self->key.p) : 0; |
123 | 123 | if (siz>10000) { |
124 | croak("FATAL: key2hash failed - 'p' too big number"); | |
124 | croak("FATAL: key2hash failed - 'p' too big number"); | |
125 | 125 | } |
126 | 126 | if (siz>0) { |
127 | 127 | mp_tohex(self->key.p, buf); |
133 | 133 | /* =====> qP */ |
134 | 134 | siz = (self->key.qP) ? ltc_mp.unsigned_size(self->key.qP) : 0; |
135 | 135 | if (siz>10000) { |
136 | croak("FATAL: key2hash failed - 'qP' too big number"); | |
136 | croak("FATAL: key2hash failed - 'qP' too big number"); | |
137 | 137 | } |
138 | 138 | if (siz>0) { |
139 | 139 | mp_tohex(self->key.qP, buf); |
145 | 145 | /* =====> dP */ |
146 | 146 | siz = (self->key.dP) ? ltc_mp.unsigned_size(self->key.dP) : 0; |
147 | 147 | if (siz>10000) { |
148 | croak("FATAL: key2hash failed - 'dP' too big number"); | |
148 | croak("FATAL: key2hash failed - 'dP' too big number"); | |
149 | 149 | } |
150 | 150 | if (siz>0) { |
151 | 151 | mp_tohex(self->key.dP, buf); |
157 | 157 | /* =====> dQ */ |
158 | 158 | siz = (self->key.dQ) ? ltc_mp.unsigned_size(self->key.dQ) : 0; |
159 | 159 | if (siz>10000) { |
160 | croak("FATAL: key2hash failed - 'dQ' too big number"); | |
160 | croak("FATAL: key2hash failed - 'dQ' too big number"); | |
161 | 161 | } |
162 | 162 | if (siz>0) { |
163 | 163 | mp_tohex(self->key.dQ, buf); |
181 | 181 | int rv; |
182 | 182 | unsigned char out[4096]; |
183 | 183 | unsigned long int out_len = 4096; |
184 | ||
184 | ||
185 | 185 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
186 | 186 | if (strnEQ(type, "private", 7)) { |
187 | 187 | rv = rsa_export(out, &out_len, PK_PRIVATE, &self->key); |
211 | 211 | STRLEN data_len=0; |
212 | 212 | unsigned char buffer[1024]; |
213 | 213 | unsigned long buffer_len = 1024; |
214 | ||
214 | ||
215 | 215 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
216 | ||
216 | ||
217 | 217 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
218 | 218 | if (strnEQ(padding, "oaep", 4)) { |
219 | 219 | hash_id = find_hash(oaep_hash); |
256 | 256 | STRLEN data_len=0; |
257 | 257 | unsigned char buffer[1024]; |
258 | 258 | unsigned long buffer_len = 1024; |
259 | ||
259 | ||
260 | 260 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
261 | ||
261 | ||
262 | 262 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
263 | 263 | if (strnEQ(padding, "oaep", 4)) { |
264 | 264 | hash_id = find_hash(oaep_hash); |
299 | 299 | STRLEN data_len=0; |
300 | 300 | unsigned char buffer[1024]; |
301 | 301 | unsigned long buffer_len = 1024; |
302 | ||
302 | ||
303 | 303 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
304 | ||
304 | ||
305 | 305 | RETVAL = newSVpvn(NULL, 0); /* undef */ |
306 | 306 | hash_id = find_hash(hash_name); |
307 | 307 | if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
335 | 335 | STRLEN data_len=0; |
336 | 336 | unsigned char *sig_ptr=NULL; |
337 | 337 | STRLEN sig_len=0; |
338 | ||
338 | ||
339 | 339 | data_ptr = (unsigned char *)SvPVbyte(data, data_len); |
340 | 340 | sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len); |
341 | ||
341 | ||
342 | 342 | RETVAL = 1; |
343 | 343 | hash_id = find_hash(hash_name); |
344 | 344 | if(hash_id==-1) croak("FATAL: find_hash failed for '%s'", hash_name); |
10 | 10 | |
11 | 11 | Newz(0, RETVAL, 1, struct prng_struct); |
12 | 12 | if (!RETVAL) croak("FATAL: Newz failed"); |
13 | ||
13 | ||
14 | 14 | id = find_prng(prng_name); |
15 | 15 | if(id==-1) croak("FATAL: find_prng failed for '%s'", prng_name); |
16 | 16 | RETVAL->id = id; |
25 | 25 | rv = RETVAL->desc->add_entropy(ent, (unsigned long)ent_len, &RETVAL->state); |
26 | 26 | if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); |
27 | 27 | } |
28 | else { | |
28 | else { | |
29 | 29 | if (rng_get_bytes(entropy_buf, 32, NULL) != 32) croak("FATAL: rng_get_bytes failed: %s", error_to_string(rv)); |
30 | 30 | rv = RETVAL->desc->add_entropy(entropy_buf, 32, &RETVAL->state); |
31 | 31 | if (rv != CRYPT_OK) croak("FATAL: PRNG_add_entropy failed: %s", error_to_string(rv)); |
72 | 72 | int rv_len; |
73 | 73 | unsigned char *rdata; |
74 | 74 | unsigned char entropy_buf[32]; |
75 | ||
75 | ||
76 | 76 | if (self->last_pid != curpid) { |
77 | 77 | rng_get_bytes(entropy_buf, 32, NULL); |
78 | 78 | self->desc->add_entropy(entropy_buf, 32, &self->state); |
79 | 79 | self->desc->ready(&self->state); |
80 | 80 | self->last_pid = curpid; |
81 | 81 | } |
82 | ||
82 | ||
83 | 83 | RETVAL = NEWSV(0, output_len); |
84 | 84 | SvPOK_only(RETVAL); |
85 | 85 | SvCUR_set(RETVAL, output_len); |