File Coverage

blib/lib/Crypt/EAX.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Crypt::EAX;
4 1     1   51941 use Moose;
  0            
  0            
5              
6             our $VERSION = "0.04";
7              
8             use Carp qw(croak);
9              
10             use Digest::CMAC;
11             use Crypt::Ctr::FullWidth;
12              
13             use namespace::clean -except => [qw(meta)];
14              
15             has key => (
16             isa => "Str",
17             is => "ro",
18             required => 1,
19             );
20              
21             has [qw(header nonce)] => (
22             isa => "Str",
23             is => "ro",
24             default => '',
25             );
26              
27             has mode => (
28             isa => "Str",
29             is => "rw",
30             );
31              
32             has N => (
33             isa => "Str",
34             is => "rw",
35             lazy => 1,
36             default => sub {
37             my $self = shift;
38             $self->omac_t( $self->n_omac, 0, $self->nonce );
39             },
40             );
41              
42             has cipher => (
43             #isa => "ClassName|Object",
44             is => "rw",
45             default => "Crypt::Rijndael",
46             );
47              
48             has fatal => (
49             isa => "Bool",
50             is => "rw",
51             default => 1,
52             );
53              
54             has ctr => (
55             isa => "Crypt::Ctr::FullWidth",
56             is => "ro",
57             lazy => 1,
58             default => sub {
59             my $self = shift;
60             Crypt::Ctr::FullWidth->new( $self->key, $self->cipher );
61             },
62             );
63              
64             has [qw(c_omac n_omac h_omac)] => (
65             isa => "Digest::CMAC",
66             is => "ro",
67             lazy => 1,
68             default => sub {
69             my $self = shift;
70             Digest::CMAC->new( $self->key, $self->cipher );
71             },
72             );
73              
74             sub BUILDARGS {
75             my ( $class, @args ) = @_;
76              
77             if ( @args == 1 ) {
78             return { key => $args[0] }
79             } elsif ( @args == 2 and $args[0] ne 'key' ) {
80             return { key => $args[0], cipher => $args[1] }
81             } else {
82             return $class->SUPER::BUILDARGS(@args);
83             }
84             };
85              
86             sub _cbc_k {
87             my ( $self, $m ) = @_;
88             return;
89             }
90              
91             sub reset {
92             my $self = shift;
93              
94             $self->ctr->reset;
95             $self->c_omac->reset;
96             $self->h_omac->reset;
97              
98             $self->ctr->set_nonce($self->N);
99              
100             $self->omac_t( $self->c_omac, 2 );
101             if ( length ( my $header = $self->header ) ) {
102             $self->omac_t( $self->h_omac, 1, $header );
103             }
104             }
105              
106             sub BUILD {
107             my ( $self, $args ) = @_;
108             $self->omac_t( $self->h_omac, 1 );
109             $self->reset;
110             }
111              
112             sub start {
113             my ( $self, $mode ) = @_;
114             $self->mode($mode);
115             }
116              
117             sub encrypt_parts {
118             my ( $self, $plain ) = @_;
119              
120             $self->start('encrypting');
121              
122             return ( $self->add_encrypt($plain), $self->finish );
123             }
124              
125             sub encrypt {
126             my ( $self, $plain ) = @_;
127             return join('', $self->encrypt_parts($plain) );
128             }
129              
130             sub decrypt_parts {
131             my ( $self, $ciphertext, $tag ) = @_;
132              
133             $self->start('decrypting');
134              
135             my $plain = $self->add_decrypt( $ciphertext );
136              
137             if ( $self->finish($tag) ) {
138             return $plain;
139             } else {
140             $self->verification_failed($ciphertext, $plain, $tag);
141             }
142             }
143              
144             sub decrypt {
145             my ( $self, $ciphertext ) = @_;
146              
147             my $blocksize = $self->blocksize;
148              
149             $ciphertext =~ s/(.{$blocksize})$//s;
150             my $tag = $1;
151              
152             $self->decrypt_parts( $ciphertext, $tag );
153             }
154              
155             sub verification_failed {
156             my $self = shift;
157              
158             if ( $self->fatal ) {
159             croak "Verification of ciphertext failed";
160             } else {
161             return;
162             }
163             }
164              
165             sub add_header {
166             my ( $self, $plain ) = @_;
167              
168             $self->h_omac->add( $plain );
169              
170             return;
171             }
172              
173             sub add_encrypt {
174             my ( $self, $plain ) = @_;
175              
176             my $ciphertext = $self->ctr->encrypt($plain) || '';
177              
178             $self->c_omac->add( $ciphertext );
179              
180             return $ciphertext;
181             }
182              
183             sub add_decrypt {
184             my ( $self, $ciphertext ) = @_;
185              
186             $self->c_omac->add( $ciphertext );
187              
188             my $plain = $self->ctr->decrypt($ciphertext);
189              
190             return $plain;
191             }
192              
193             sub finish {
194             my ( $self, @args ) = @_;
195              
196             die "No current mode. Did you forget to call start()?" unless $self->mode;
197              
198             my $tag = $self->tag;
199              
200             if ( $self->mode eq 'encrypting' ) {
201             return $tag;
202             } elsif ( $self->mode eq 'decrypting' ) {
203             return 1 if $tag eq $args[0];
204             return;
205             } else {
206             croak "Unknown mode: " . $self->mode;
207             }
208             }
209              
210             sub tag {
211             my $self = shift;
212              
213             my $N = $self->N;
214             my $H = $self->h_omac->digest;
215             my $C = $self->c_omac->digest;
216              
217             $self->reset;
218              
219             return $N ^ $H ^ $C;
220             }
221              
222             sub omac_t {
223             my ( $self, $omac, $t, @msg ) = @_;
224              
225             my $blocksize = $self->blocksize;
226             my $padsize = $blocksize -1;
227              
228             my $num = pack("x$padsize C", $t);
229              
230             $omac->add( $num );
231              
232             $omac->add( $_ ) for @msg;
233              
234             return $omac->digest if defined wantarray;
235             }
236              
237             sub blocksize {
238             my $self = shift;
239              
240             $self->c_omac->{cipher}->blocksize;
241             }
242              
243             __PACKAGE__->meta->make_immutable if __PACKAGE__->meta->can("make_immutable");
244              
245             __PACKAGE__;
246              
247             __END__
248              
249             =pod
250              
251             =head1 NAME
252              
253             Crypt::EAX - Encrypt and authenticate data in EAX mode
254              
255             =head1 SYNOPSIS
256              
257             use Crypt::EAX;
258              
259             my $c = Crypt::EAX->new(
260             key => $key,
261             cipher => "Crypt::Rijndael",
262             header => $header, # optional
263             nonce => $nonce, # optional but reccomended
264             fatal => 1,
265             );
266              
267             my $ciphertext = $c->encrypt( $message );
268              
269             $ciphertext ^= "moose"; # corrupt it
270              
271             $c->decrypt( $ciphertext ); # dies
272              
273             $ciphertext ^= "moose"; # xor is reversible
274              
275             is( $c->decrypt( $ciphertext ), $msg );
276              
277             =head1 DESCRIPTION
278              
279             EAX is a cipher chaining mode with integrated message authentication. This type
280             of encryption mode is called AEAD, or Authenticated Encryption with Associated
281             Data.
282              
283             The purpuse of AEAD modes is that you can safely encrypt and sign a value with
284             a shared key. The message will not decrypt if it has been tampered with.
285              
286             There are various reasons why just C<encrypt(mac($message))> is not safe, but I
287             don't exactly know them since I'm not a crptographer. For more info use The
288             Oracle Google.
289              
290             Read more about EAX AEAD here:
291              
292             =over 4
293              
294             =item L<http://en.wikipedia.org/wiki/EAX_mode>
295              
296             =item L<http://en.wikipedia.org/wiki/AEAD_block_cipher_modes_of_operation>
297              
298             =back
299              
300             =head1 CONFIGURATION
301              
302             =over 4
303              
304             =item key
305              
306             The key used to encrypt/decrypt and authenticate. Passed verbatim to
307             L<Crypt::Ctr::FullWidth> and L<Digest::CMAC>.
308              
309             =item cipher
310              
311             Defaults to L<Crypt::Rijndael>. Likewise passed verbatim.
312              
313             =item fatal
314              
315             Whether or not failed verification dies or returns a false value.
316              
317             =item header
318              
319             Additional data to be authenticated but not encrypted.
320              
321             Note that it's also possible to incrementally add the header using
322             C<add_header>.
323              
324             If the C<header> option is passed instead then C<add_header> will be called
325             with it as an argument every time C<reset> is called.
326              
327             This will not be included in the resulting ciphertext, but the ciphertext must
328             be authenticated against it.
329              
330             Presumably you are supposed to encode the ciphertext and header together in
331             your message.
332              
333             This is the Associated Data part of AEAD.
334              
335             Be careful if you deconstruct the message naively, like this:
336              
337             my ( $header, $ciphertext ) = unpack("N/a a*", $message);
338              
339             since you are inherently trusting the input data already, before it's been
340             verified (the N/ part can be altered, and though knowing Perl this is probably
341             safe, I wouldn't count on it). The specific attack in this case is if a large
342             number is encoded by the attacker in the N field then it could trick your
343             program into trying allocate 4GB of memory in this particular example.
344              
345             At any rate do not trust the header till the ciphertext has been successfully
346             decrypted.
347              
348             =item nonce
349              
350             The nonce to use for authentication. Should be unique. See
351             L<http://en.wikipedia.org/wiki/Cryptographic_nonce>.
352              
353             It is OK to pass this along with the ciphertext, much like the salt bit in
354             C<crypt>.
355              
356             An empty value is allowed and is in fact the default, but this is not safe
357             against replay attacks.
358              
359             =back
360              
361             =head1 METHODS
362              
363             =over 4
364              
365             =item new %args
366              
367             Instantiate a new L<Crypt::EAX> object.
368              
369             See L</CONFIGURATION>.
370              
371             =item encrypt $plaintext
372              
373             =item decrypt $ciphertext
374              
375             Single step encryption/decryption.
376              
377             The tag is appended to the ciphertext.
378              
379             =item encrypt_parts $plaintext
380              
381             Returns the ciphertext and tag as separate tags.
382              
383             =item decrypt_parts $ciphertext, $tag
384              
385             Decrypts and verifies the message.
386              
387             =item start $mode
388              
389             Takes either C<encrypting> or C<decrypting>.
390              
391             =item finish ?$tag
392              
393             If encrypting, returns the tag.
394              
395             If decrypting, checks that $tag is equal to the calculated tag.
396              
397             Used by C<encrypt_parts> and C<decrypt_parts>.
398              
399             =item add_encrypt $text
400              
401             =item add_decrypt $ciphertext
402              
403             Streaming mode of operation. Requires a call to C<start> before and C<finish>
404             after. Used by C<decrypt_parts> and C<encrypt_parts>.
405              
406             =item add_header $header
407              
408             Add header data that will be authenticated as well. See C<header> for more
409             details.
410              
411             =item verification_failed
412              
413             Called when verification fails. Dies when C<fatal> is set, returns a false
414             value otherwise.
415              
416             =back
417              
418             =head1 TODO
419              
420             =over 4
421              
422             =item *
423              
424             Consider disallowing an empty nonce.
425              
426             Can anyone advise on this?
427              
428             =back
429              
430             =head1 SEE ALSO
431              
432             L<Digest::CMAC>, L<Crypt::Ctr>, L<Crypt::Ctr::FullWidth>, L<Crypt::Util>
433              
434             =head1 VERSION CONTROL
435              
436             This module is maintained using Darcs. You can get the latest version from
437             L<http://nothingmuch.woobling.org/code>, and use C<darcs send> to commit
438             changes.
439              
440             =head1 AUTHOR
441              
442             Yuval Kogman <nothingmuch@woobling.org>
443              
444             =head1 COPYRIGHT & LICENSE
445              
446             Copyright (c) 2007 Yuval Kogman. All rights reserved
447             This program is free software; you can redistribute it and/or modify it
448             under the terms of the MIT license or the same terms as Perl itself.
449              
450             =cut
451              
452