Package list libcryptx-perl / 2fa3734
using libtomcrypt's padding functions: padding_depad + padding_pad Karel Miko 2 years ago
7 changed file(s) with 175 addition(s) and 82 deletion(s). Raw diff Collapse all Expand all
113113 # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64',
114114 # 'SEED', 'Skipjack', 'Twofish', 'XTEA', 'IDEA', 'Serpent'
115115 # simply any <NAME> for which there exists Crypt::Cipher::<NAME>
116 # $padding .... 0 no padding (plaintext size has to be myltiple of block length)
116 # $padding .... 0 no padding (plaintext size has to be multiple of block length)
117117 # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT
118118 # 2 Crypt::CBC's "oneandzeroes"
119 # 3 ANSI X.923 padding
120 # 4 zero padding
121 # 5 zero padding (+a block of zeros if the output length is divisible by the blocksize)
119122 # $cipher_rounds ... optional num of rounds for given cipher
120123 [%-ELSE%]
121124 my $m = Crypt::Mode::[%orig_name%]->new($name);
222222 finish(Crypt::Mode::[%orig_name%] self)
223223 CODE:
224224 {
225 unsigned char tmp_block[MAXBLOCKSIZE], ch;
226 int i, j, rv, blen = (&self->state)->blocklen;
225 unsigned char tmp_block[MAXBLOCKSIZE];
226 int rv;
227 unsigned long blen = (&self->state)->blocklen;
228 unsigned long padmode;
227229
228230 if (self->direction == 1) {
229 if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen");
230 if (self->padding_mode == 1) { /* pkcs5|7 padding */
231 i = blen - self->padlen;
232 if (i == 0) i = blen;
233 for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i;
231 if (self->padlen < 0 || self->padlen >= blen) croak("FATAL: invalid padlen");
232 if (self->padding_mode != 0) {
233 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7 | (&self->state)->blocklen; }
234 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO | (&self->state)->blocklen; }
235 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923 | (&self->state)->blocklen; }
236 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO | (&self->state)->blocklen; }
237 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS | (&self->state)->blocklen; }
238 else { croak("FATAL: unknown padding"); }
239 blen = sizeof(self->pad);
240 rv = padding_pad(self->pad, self->padlen, &blen, padmode);
241 if (rv != CRYPT_OK) croak("FATAL: padding_pad failed: %s", error_to_string(rv));
234242 rv = [%lc_name%]_encrypt(self->pad, tmp_block, blen, &self->state);
235243 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv));
236244 }
237 else if (self->padding_mode == 2) { /* oneandzeroes padding */
238 self->pad[self->padlen] = 0x80;
239 for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0;
240 rv = [%lc_name%]_encrypt(self->pad, tmp_block, blen, &self->state);
241 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_encrypt failed: %s", error_to_string(rv));
242 }
243245 else {
244 if (self->padlen>0) croak("FATAL: [%lc_name%]_encrypt, input data length not multiple of %d", blen);
246 if (self->padlen > 0) croak("FATAL: [%lc_name%]_encrypt, input data length not multiple of %d", blen);
245247 blen = 0;
246248 }
247249 }
250252 if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen);
251253 rv = [%lc_name%]_decrypt(self->pad, tmp_block, blen, &self->state);
252254 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv));
253 if (self->padding_mode == 0) { /* no padding */
254 /* we already have blen */
255 }
256 else if (self->padding_mode == 1) { /* pkcs5|7 padding */
257 ch = tmp_block[blen-1];
258 blen = blen - (ch > blen ? blen : ch);
259 }
260 else if (self->padding_mode == 2) { /* oneandzeroes padding */
261 while ((unsigned char)tmp_block[blen - 1] == 0x00) blen--;
262 if ((unsigned char)tmp_block[blen - 1] == 0x80) blen--;
263 if (blen < 0) blen = 0;
255 if (self->padding_mode != 0) {
256 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7; }
257 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO; }
258 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923; }
259 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO; }
260 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS; }
261 else { croak("FATAL: unknown padding"); }
262 rv = padding_depad(tmp_block, &blen, padmode);
263 if (rv != CRYPT_OK) croak("FATAL: padding_depad failed: %s", error_to_string(rv));
264 }
265 else {
266 /* "no padding" == there is no need to do anything */
264267 }
265268 }
266269 else {
268271 }
269272 }
270273 else {
271 XSRETURN_UNDEF;
274 croak("FATAL: invalid direction");
272275 }
273276
274277 self->direction = 0;
210210 finish(Crypt::Mode::CBC self)
211211 CODE:
212212 {
213 unsigned char tmp_block[MAXBLOCKSIZE], ch;
214 int i, j, rv, blen = (&self->state)->blocklen;
213 unsigned char tmp_block[MAXBLOCKSIZE];
214 int rv;
215 unsigned long blen = (&self->state)->blocklen;
216 unsigned long padmode;
215217
216218 if (self->direction == 1) {
217 if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen");
218 if (self->padding_mode == 1) { /* pkcs5|7 padding */
219 i = blen - self->padlen;
220 if (i == 0) i = blen;
221 for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i;
219 if (self->padlen < 0 || self->padlen >= blen) croak("FATAL: invalid padlen");
220 if (self->padding_mode != 0) {
221 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7 | (&self->state)->blocklen; }
222 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO | (&self->state)->blocklen; }
223 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923 | (&self->state)->blocklen; }
224 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO | (&self->state)->blocklen; }
225 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS | (&self->state)->blocklen; }
226 else { croak("FATAL: unknown padding"); }
227 blen = sizeof(self->pad);
228 rv = padding_pad(self->pad, self->padlen, &blen, padmode);
229 if (rv != CRYPT_OK) croak("FATAL: padding_pad failed: %s", error_to_string(rv));
222230 rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state);
223231 if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv));
224232 }
225 else if (self->padding_mode == 2) { /* oneandzeroes padding */
226 self->pad[self->padlen] = 0x80;
227 for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0;
228 rv = cbc_encrypt(self->pad, tmp_block, blen, &self->state);
229 if (rv != CRYPT_OK) croak("FATAL: cbc_encrypt failed: %s", error_to_string(rv));
230 }
231233 else {
232 if (self->padlen>0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen);
234 if (self->padlen > 0) croak("FATAL: cbc_encrypt, input data length not multiple of %d", blen);
233235 blen = 0;
234236 }
235237 }
238240 if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen);
239241 rv = cbc_decrypt(self->pad, tmp_block, blen, &self->state);
240242 if (rv != CRYPT_OK) croak("FATAL: cbc_decrypt failed: %s", error_to_string(rv));
241 if (self->padding_mode == 0) { /* no padding */
242 /* we already have blen */
243 }
244 else if (self->padding_mode == 1) { /* pkcs5|7 padding */
245 ch = tmp_block[blen-1];
246 blen = blen - (ch > blen ? blen : ch);
247 }
248 else if (self->padding_mode == 2) { /* oneandzeroes padding */
249 while ((unsigned char)tmp_block[blen - 1] == 0x00) blen--;
250 if ((unsigned char)tmp_block[blen - 1] == 0x80) blen--;
251 if (blen < 0) blen = 0;
243 if (self->padding_mode != 0) {
244 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7; }
245 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO; }
246 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923; }
247 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO; }
248 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS; }
249 else { croak("FATAL: unknown padding"); }
250 rv = padding_depad(tmp_block, &blen, padmode);
251 if (rv != CRYPT_OK) croak("FATAL: padding_depad failed: %s", error_to_string(rv));
252 }
253 else {
254 /* "no padding" == there is no need to do anything */
252255 }
253256 }
254257 else {
256259 }
257260 }
258261 else {
259 XSRETURN_UNDEF;
262 croak("FATAL: invalid direction");
260263 }
261264
262265 self->direction = 0;
203203 finish(Crypt::Mode::ECB self)
204204 CODE:
205205 {
206 unsigned char tmp_block[MAXBLOCKSIZE], ch;
207 int i, j, rv, blen = (&self->state)->blocklen;
206 unsigned char tmp_block[MAXBLOCKSIZE];
207 int rv;
208 unsigned long blen = (&self->state)->blocklen;
209 unsigned long padmode;
208210
209211 if (self->direction == 1) {
210 if (self->padlen<0 || self->padlen>=blen) croak("FATAL: invalid padlen");
211 if (self->padding_mode == 1) { /* pkcs5|7 padding */
212 i = blen - self->padlen;
213 if (i == 0) i = blen;
214 for(j=self->padlen; j<blen; j++) self->pad[j] = (unsigned char)i;
212 if (self->padlen < 0 || self->padlen >= blen) croak("FATAL: invalid padlen");
213 if (self->padding_mode != 0) {
214 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7 | (&self->state)->blocklen; }
215 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO | (&self->state)->blocklen; }
216 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923 | (&self->state)->blocklen; }
217 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO | (&self->state)->blocklen; }
218 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS | (&self->state)->blocklen; }
219 else { croak("FATAL: unknown padding"); }
220 blen = sizeof(self->pad);
221 rv = padding_pad(self->pad, self->padlen, &blen, padmode);
222 if (rv != CRYPT_OK) croak("FATAL: padding_pad failed: %s", error_to_string(rv));
215223 rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state);
216224 if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv));
217225 }
218 else if (self->padding_mode == 2) { /* oneandzeroes padding */
219 self->pad[self->padlen] = 0x80;
220 for(j=self->padlen+1; j<blen; j++) self->pad[j] = 0;
221 rv = ecb_encrypt(self->pad, tmp_block, blen, &self->state);
222 if (rv != CRYPT_OK) croak("FATAL: ecb_encrypt failed: %s", error_to_string(rv));
223 }
224226 else {
225 if (self->padlen>0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen);
227 if (self->padlen > 0) croak("FATAL: ecb_encrypt, input data length not multiple of %d", blen);
226228 blen = 0;
227229 }
228230 }
231233 if (self->padlen != blen) croak("FATAL: cipher text length has to be multiple of %d (%d)", blen, self->padlen);
232234 rv = ecb_decrypt(self->pad, tmp_block, blen, &self->state);
233235 if (rv != CRYPT_OK) croak("FATAL: ecb_decrypt failed: %s", error_to_string(rv));
234 if (self->padding_mode == 0) { /* no padding */
235 /* we already have blen */
236 }
237 else if (self->padding_mode == 1) { /* pkcs5|7 padding */
238 ch = tmp_block[blen-1];
239 blen = blen - (ch > blen ? blen : ch);
240 }
241 else if (self->padding_mode == 2) { /* oneandzeroes padding */
242 while ((unsigned char)tmp_block[blen - 1] == 0x00) blen--;
243 if ((unsigned char)tmp_block[blen - 1] == 0x80) blen--;
244 if (blen < 0) blen = 0;
236 if (self->padding_mode != 0) {
237 if (self->padding_mode == 1) { padmode = LTC_PAD_PKCS7; }
238 else if (self->padding_mode == 2) { padmode = LTC_PAD_ONE_AND_ZERO; }
239 else if (self->padding_mode == 3) { padmode = LTC_PAD_ANSI_X923; }
240 else if (self->padding_mode == 4) { padmode = LTC_PAD_ZERO; }
241 else if (self->padding_mode == 5) { padmode = LTC_PAD_ZERO_ALWAYS; }
242 else { croak("FATAL: unknown padding"); }
243 rv = padding_depad(tmp_block, &blen, padmode);
244 if (rv != CRYPT_OK) croak("FATAL: padding_depad failed: %s", error_to_string(rv));
245 }
246 else {
247 /* "no padding" == there is no need to do anything */
245248 }
246249 }
247250 else {
249252 }
250253 }
251254 else {
252 XSRETURN_UNDEF;
255 croak("FATAL: invalid direction");
253256 }
254257
255258 self->direction = 0;
6969 # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64',
7070 # 'SEED', 'Skipjack', 'Twofish', 'XTEA', 'IDEA', 'Serpent'
7171 # simply any <NAME> for which there exists Crypt::Cipher::<NAME>
72 # $padding .... 0 no padding (plaintext size has to be myltiple of block length)
72 # $padding .... 0 no padding (plaintext size has to be multiple of block length)
7373 # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT
7474 # 2 Crypt::CBC's "oneandzeroes"
75 # 3 ANSI X.923 padding
76 # 4 zero padding
77 # 5 zero padding (+a block of zeros if the output length is divisible by the blocksize)
7578 # $cipher_rounds ... optional num of rounds for given cipher
7679
7780 =head2 encrypt
7070 # 'SAFERP', 'SAFER_K128', 'SAFER_K64', 'SAFER_SK128', 'SAFER_SK64',
7171 # 'SEED', 'Skipjack', 'Twofish', 'XTEA', 'IDEA', 'Serpent'
7272 # simply any <NAME> for which there exists Crypt::Cipher::<NAME>
73 # $padding .... 0 no padding (plaintext size has to be myltiple of block length)
73 # $padding .... 0 no padding (plaintext size has to be multiple of block length)
7474 # 1 PKCS5 padding, Crypt::CBC's "standard" - DEFAULT
7575 # 2 Crypt::CBC's "oneandzeroes"
76 # 3 ANSI X.923 padding
77 # 4 zero padding
78 # 5 zero padding (+a block of zeros if the output length is divisible by the blocksize)
7679 # $cipher_rounds ... optional num of rounds for given cipher
7780
7881 =head2 encrypt
66 use Test::More;
77
88 plan skip_all => "No JSON::* module installed" unless eval { require JSON::PP } || eval { require JSON::XS } || eval { require Cpanel::JSON::XS };
9 plan skip_all => "Temporarily disabled";
910 plan tests => 1298;
1011
1112 use CryptX;
1213 use Crypt::Misc 'read_rawfile';
1314 use Crypt::Digest 'digest_data';
15
16 if (0) {
17 use Crypt::Mode::CBC;
18
19 my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/aes_cbc_pkcs5_test.json';
20 for my $g (@{$tests->{testGroups}}) {
21 my $type = $g->{type};
22 for my $t (@{$g->{tests}}) {
23 my $tcId = $t->{tcId}; # 1
24 my $comment = $t->{comment}; # ""
25 my $result = $t->{result}; # "valid"
26 my $ct = pack "H*", $t->{ct}; # "5d349ead175ef6b1def6fd"
27 my $iv = pack "H*", $t->{iv}; # "752abad3e0afb5f434dc4310"
28 my $key = pack "H*", $t->{key}; # "ee8e1ed9ff2540ae8f2ba9f50bc2f27c"
29 my $msg = pack "H*", $t->{msg}; # "48656c6c6f20776f726c64"
30 # do the test
31 my $enc = Crypt::Mode::CBC->new('AES', 1); # 1 = PKCS5 padding
32 my $ct2 = eval { $enc->encrypt($msg, $key, $iv) };
33 my $dec = Crypt::Mode::CBC->new('AES', 1); # 1 = PKCS5 padding
34 my $pt2 = eval { $dec->decrypt($ct, $key, $iv) };
35 my $testname = "type=$type tcId=$tcId comment='$comment' expected-result=$result";
36 if ($result eq 'valid' || $result eq 'acceptable') {
37 is(unpack("H*", $ct2), $t->{ct}, "$testname CT-v");
38 is(unpack("H*", $pt2), $t->{msg}, "$testname PT-v");
39 }
40 elsif ($result eq 'invalid') {
41 #isnt(unpack("H*", $ct2), $t->{ct}, "$testname CT-i");
42 #isnt(unpack("H*", $tag2), $t->{tag}, "$testname TAG-i");
43 is($pt2, undef, "$testname PT-i");
44 }
45 else {
46 ok(0, "UNEXPECTED result=$result");
47 }
48 }
49 }
50 }
1451
1552 if (0) {
1653 use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify);
3168 # do the test
3269 my ($ct2, $tag2) = eval { gcm_encrypt_authenticate('AES', $key, $iv, $aad, $msg) };
3370 my $pt2 = eval { gcm_decrypt_verify('AES', $key, $iv, $aad, $ct, $tag) };
71 my $testname = "type=$type tcId=$tcId comment='$comment' expected-result=$result";
72 if ($result eq 'valid' || $result eq 'acceptable') {
73 is(unpack("H*", $ct2), $t->{ct}, "$testname CT-v");
74 is(unpack("H*", $tag2), $t->{tag}, "$testname TAG-v");
75 is(unpack("H*", $pt2), $t->{msg}, "$testname PT-v");
76 }
77 elsif ($result eq 'invalid') {
78 #isnt(unpack("H*", $ct2), $t->{ct}, "$testname CT-i");
79 #isnt(unpack("H*", $tag2), $t->{tag}, "$testname TAG-i");
80 is($pt2, undef, "$testname PT-i");
81 }
82 else {
83 ok(0, "UNEXPECTED result=$result");
84 }
85 }
86 }
87 }
88
89 if (0) {
90 use Crypt::AuthEnc::CCM qw(ccm_encrypt_authenticate ccm_decrypt_verify);
91
92 my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/aes_ccm_test.json';
93 for my $g (@{$tests->{testGroups}}) {
94 my $type = $g->{type};
95 my $tlen = $g->{tagSize};
96 for my $t (@{$g->{tests}}) {
97 my $tcId = $t->{tcId}; # 1
98 my $comment = $t->{comment}; # ""
99 my $result = $t->{result}; # "valid"
100 my $aad = pack "H*", $t->{aad}; # "6578616d706c65"
101 my $ct = pack "H*", $t->{ct}; # "5d349ead175ef6b1def6fd"
102 my $iv = pack "H*", $t->{iv}; # "752abad3e0afb5f434dc4310"
103 my $key = pack "H*", $t->{key}; # "ee8e1ed9ff2540ae8f2ba9f50bc2f27c"
104 my $msg = pack "H*", $t->{msg}; # "48656c6c6f20776f726c64"
105 my $tag = pack "H*", $t->{tag}; # "4fbcdeb7e4793f4a1d7e4faa70100af1"
106 # do the test
107 my ($ct2, $tag2) = eval { ccm_encrypt_authenticate('AES', $key, $iv, $aad, $tlen/8, $msg) };
108 my $pt2 = eval { ccm_decrypt_verify('AES', $key, $iv, $aad, $ct, $tag) };
34109 my $testname = "type=$type tcId=$tcId comment='$comment' expected-result=$result";
35110 if ($result eq 'valid' || $result eq 'acceptable') {
36111 is(unpack("H*", $ct2), $t->{ct}, "$testname CT-v");
146221 }
147222 }
148223
149 if (1) {
224 if (0) {
150225 use Crypt::PK::ECC;
151226 my @files = ( "t/wycheproof/ecdsa_test.json" );
152227 #push @files, glob("t/wycheproof/ecdsa_secp*.json");