File Coverage

blib/lib/Crypt/DRBG/HMAC.pm
Criterion Covered Total %
statement 69 69 100.0
branch 9 10 90.0
condition 3 5 60.0
subroutine 10 10 100.0
pod 1 1 100.0
total 92 95 96.8


line stmt bran cond sub pod time code
1             package Crypt::DRBG::HMAC;
2             $Crypt::DRBG::HMAC::VERSION = '0.000001';
3 11     11   15911 use 5.006;
  11         42  
4 11     11   64 use strict;
  11         20  
  11         222  
5 11     11   54 use warnings;
  11         13  
  11         361  
6              
7 11     11   1526 use parent 'Crypt::DRBG';
  11         618  
  11         64  
8              
9 11     11   3210 use Digest::SHA ();
  11         7633  
  11         7785  
10              
11             =head1 NAME
12              
13             Crypt::DRBG::HMAC - Fast, cryptographically secure PRNG
14              
15             =head1 SYNOPSIS
16              
17             use Crypt::DRBG::HMAC;
18              
19             my $drbg = Crypt::DRBG::HMAC->new(auto => 1);
20             my $data = $drbg->generate(42);
21             ... # do something with your 42 bytes here
22              
23             my $drbg2 = Crypt::DRBG::HMAC->new(seed => "my very secret seed");
24             my $data2 = $drbg->generate(42);
25              
26             =head1 DESCRIPTION
27              
28             Crypt::DRBG::HMAC is an implementation of the HMAC_DRBG from NIST SP800-90A. It
29             is a fast, cryptographically secure PRNG. By default, it uses HMAC-SHA-512.
30              
31             However, if provided a seed, it will produce the same sequence of bytes I
32             called the same way each time>. This makes it useful for simulations that
33             require good but repeatable random numbers.
34              
35             Note, however, that due to the way the DRBGs are designed, making a single
36             request and making multiple requests for the same number of bytes will result in
37             different data. For example, two 16-byte requests will not produce the same
38             values as one 32-byte request.
39              
40             This class derives from Crypt::DRBG, which provides several utility functions.
41              
42             =head1 SUBROUTINES/METHODS
43              
44             =head2 Crypt::DRBG::HMAC->new(%params)
45              
46             Creates a new Crypt::DRBG::HMAC.
47              
48             %params can contain all valid values for Crypt::DRBG::initialize, plus the
49             following.
50              
51             =over 4
52              
53             =item algo
54              
55             The algorithm to use for generating bytes. The default is "512", for
56             HMAC-SHA-512. This provides optimal performance for 64-bit machines.
57              
58             If Perl (and hence Digest::SHA) was built with a compiler lacking 64-bit integer
59             support, use "256" here. "256" may also provide better performance for 32-bit
60             machines.
61              
62             =back
63              
64             =cut
65              
66             sub new {
67 1381     1381 1 4552898 my ($class, %params) = @_;
68              
69 1381   33     7211 $class = ref($class) || $class;
70 1381         3151 my $self = bless {}, $class;
71              
72 1381   100     6360 my $algo = $self->{algo} = $params{algo} || '512';
73 1381         3334 $algo =~ tr{/}{}d;
74 1381 50       10402 $self->{s_func} = Digest::SHA->can("hmac_sha$algo") or
75             die "Unsupported algorithm '$algo'";
76 1381 100       6697 $self->{seedlen} = $algo =~ /^(384|512)$/ ? 111 : 55;
77 1381         2824 $self->{reseed_interval} = 4294967295; # (2^32)-1
78 1381         2567 $self->{bytes_per_request} = 2 ** 16;
79 1381         4486 $self->{outlen} = substr($algo, -3) / 8;
80 1381         3132 $self->{security_strength} = $self->{outlen} / 2;
81 1381         3568 $self->{min_length} = $self->{security_strength};
82 1381         2184 $self->{max_length} = 4294967295; # (2^32)-1
83              
84 1381         6262 $self->initialize(%params);
85              
86 1380         5377 return $self;
87             }
88              
89             sub _seed {
90 1380     1380   2160 my ($self, $seed) = @_;
91              
92 1380         3107 my $k = "\x00" x $self->{outlen};
93 1380         2555 my $v = "\x01" x $self->{outlen};
94 1380         4605 $self->{state} = {k => $k, v => $v};
95 1380         3358 return $self->_reseed($seed);
96             }
97              
98             sub _reseed {
99 1386     1386   2356 my ($self, $seed) = @_;
100              
101 1386         3146 $self->_update($seed);
102 1386         2588 $self->{reseed_counter} = 1;
103 1386         3793 return 1;
104             }
105              
106             sub _update {
107 5474     5474   8265 my ($self, $seed) = @_;
108              
109 5474 100       11824 my $data = defined $seed ? $seed : '';
110              
111 5474         7925 my $func = $self->{s_func};
112 5474         8018 my $state = $self->{state};
113 5474         6632 my ($k, $v) = @{$state}{qw/k v/};
  5474         12316  
114 5474         69502 $k = $func->("$v\x00$data", $k);
115 5474         58628 $v = $func->($v, $k);
116 5474 100       13584 if (defined $seed) {
117 4074         45997 $k = $func->("$v\x01$data", $k);
118 4074         44499 $v = $func->($v, $k);
119             }
120 5474         8297 @{$state}{qw/k v/} = ($k, $v);
  5474         13176  
121 5474         11709 return 1;
122             }
123              
124             =head2 $drbg->generate($bytes, $additional_data)
125              
126             Generate and return $bytes bytes. $bytes cannot exceed 2^16.
127              
128             If $additional_data is specified, add this additional data to the DRBG.
129              
130             =cut
131              
132             sub _generate {
133 2744     2744   4282 my ($self, $len, $seed) = @_;
134              
135 2744         8096 $self->_check_reseed($len);
136 2744 100       7496 $self->_update($seed) if defined $seed;
137              
138 2744         7027 my $count = ($len + ($self->{outlen} - 1)) / $self->{outlen};
139 2744         4089 my $data = '';
140 2744         4053 my $state = $self->{state};
141 2744         3264 my ($k, $v) = @{$state}{qw/k v/};
  2744         6166  
142 2744         4233 my $func = $self->{s_func};
143 2744         7983 for (1..$count) {
144 10920         116112 $v = $func->($v, $k);
145 10920         20317 $data .= $v;
146             }
147 2744         4422 $self->{reseed_counter}++;
148 2744         4193 @{$state}{qw/k v/} = ($k, $v);
  2744         6954  
149 2744         6970 $self->_update($seed);
150 2744         12783 return substr($data, 0, $len);
151             }
152              
153             =head1 AUTHOR
154              
155             brian m. carlson, C<< >>
156              
157             =head1 BUGS
158              
159             Please report any bugs or feature requests to C, or through
160             the web interface at L. I will be notified, and then you'll
161             automatically be notified of progress on your bug as I make changes.
162              
163              
164              
165              
166             =head1 SUPPORT
167              
168             You can find documentation for this module with the perldoc command.
169              
170             perldoc Crypt::DRBG::HMAC
171              
172              
173             You can also look for information at:
174              
175             =over 4
176              
177             =item * RT: CPAN's request tracker (report bugs here)
178              
179             L
180              
181             =item * AnnoCPAN: Annotated CPAN documentation
182              
183             L
184              
185             =item * CPAN Ratings
186              
187             L
188              
189             =item * Search CPAN
190              
191             L
192              
193             =back
194              
195              
196             =head1 ACKNOWLEDGEMENTS
197              
198              
199             =head1 LICENSE AND COPYRIGHT
200              
201             Copyright 2015 brian m. carlson.
202              
203             This program is distributed under the MIT (X11) License:
204             L
205              
206             Permission is hereby granted, free of charge, to any person
207             obtaining a copy of this software and associated documentation
208             files (the "Software"), to deal in the Software without
209             restriction, including without limitation the rights to use,
210             copy, modify, merge, publish, distribute, sublicense, and/or sell
211             copies of the Software, and to permit persons to whom the
212             Software is furnished to do so, subject to the following
213             conditions:
214              
215             The above copyright notice and this permission notice shall be
216             included in all copies or substantial portions of the Software.
217              
218             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
219             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
220             OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
221             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
222             HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
223             WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
224             FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
225             OTHER DEALINGS IN THE SOFTWARE.
226              
227              
228             =cut
229              
230             1; # End of Crypt::DRBG::HMAC