Passwörter: Hash-Verfahren PBKDF2 unterstützen und als Standard nutzen
[kivitendo-erp.git] / modules / fallback / PBKDF2 / Tiny.pm
1 use strict;
2 use warnings;
3
4 package PBKDF2::Tiny;
5 # ABSTRACT: Minimalist PBKDF2 (RFC 2898) with HMAC-SHA1 or HMAC-SHA2
6
7 our $VERSION = '0.005';
8
9 use Carp ();
10 use Exporter 5.57 qw/import/;
11
12 our @EXPORT_OK = qw/derive derive_hex verify verify_hex hmac digest_fcn/;
13
14 my ( $BACKEND, $LOAD_ERR );
15 for my $mod (qw/Digest::SHA Digest::SHA::PurePerl/) {
16     $BACKEND = $mod, last if eval "require $mod; 1";
17     $LOAD_ERR ||= $@;
18 }
19 die $LOAD_ERR if !$BACKEND;
20
21 #--------------------------------------------------------------------------#
22 # constants and lookup tables
23 #--------------------------------------------------------------------------#
24
25 # function coderef placeholder, block size in bytes, digest size in bytes
26 my %DIGEST_TYPES = (
27     'SHA-1'   => [ undef, 64,  20 ],
28     'SHA-224' => [ undef, 64,  28 ],
29     'SHA-256' => [ undef, 64,  32 ],
30     'SHA-384' => [ undef, 128, 48 ],
31     'SHA-512' => [ undef, 128, 64 ],
32 );
33
34 for my $type ( keys %DIGEST_TYPES ) {
35     no strict 'refs';
36     ( my $name = lc $type ) =~ s{-}{};
37     $DIGEST_TYPES{$type}[0] = \&{"$BACKEND\::$name"};
38 }
39
40 my %INT = map { $_ => pack( "N", $_ ) } 1 .. 16;
41
42 #--------------------------------------------------------------------------#
43 # public functions
44 #--------------------------------------------------------------------------#
45
46 #pod =func derive
47 #pod
48 #pod     $dk = derive( $type, $password, $salt, $iterations, $dk_length )
49 #pod
50 #pod The C<derive> function outputs a binary string with the derived key.
51 #pod The first argument indicates the digest function to use.  It must be one
52 #pod of: SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512.
53 #pod
54 #pod If a password or salt are not provided, they default to the empty string, so
55 #pod don't do that!  L<RFC 2898
56 #pod recommends|https://tools.ietf.org/html/rfc2898#section-4.1> a random salt of at
57 #pod least 8 octets.  If you need a cryptographically strong salt, consider
58 #pod L<Crypt::URandom>.
59 #pod
60 #pod The password and salt should encoded as octet strings. If not (i.e. if
61 #pod Perl's internal 'UTF8' flag is on), then an exception will be thrown.
62 #pod
63 #pod The number of iterations defaults to 1000 if not provided.  If the derived
64 #pod key length is not provided, it defaults to the output size of the digest
65 #pod function.
66 #pod
67 #pod =cut
68
69 sub derive {
70     my ( $type, $passwd, $salt, $iterations, $dk_length ) = @_;
71
72     my ( $digester, $block_size, $digest_length ) = digest_fcn($type);
73
74     $passwd = '' unless defined $passwd;
75     $salt   = '' unless defined $salt;
76     $iterations ||= 1000;
77     $dk_length  ||= $digest_length;
78
79     # we insist on octet strings for password and salt
80     Carp::croak("password must be an octet string, not a character string")
81       if utf8::is_utf8($passwd);
82     Carp::croak("salt must be an octet string, not a character string")
83       if utf8::is_utf8($salt);
84
85     my $key = ( length($passwd) > $block_size ) ? $digester->($passwd) : $passwd;
86     my $passes = int( $dk_length / $digest_length );
87     $passes++ if $dk_length % $digest_length; # need part of an extra pass
88
89     my $dk = "";
90     for my $i ( 1 .. $passes ) {
91         $INT{$i} ||= pack( "N", $i );
92         my $digest = my $result =
93           "" . hmac( $salt . $INT{$i}, $key, $digester, $block_size );
94         for my $iter ( 2 .. $iterations ) {
95             $digest = hmac( $digest, $key, $digester, $block_size );
96             $result ^= $digest;
97         }
98         $dk .= $result;
99     }
100
101     return substr( $dk, 0, $dk_length );
102 }
103
104 #pod =func derive_hex
105 #pod
106 #pod Works just like L</derive> but outputs a hex string.
107 #pod
108 #pod =cut
109
110 sub derive_hex { unpack( "H*", &derive ) }
111
112 #pod =func verify
113 #pod
114 #pod     $bool = verify( $dk, $type, $password, $salt, $iterations, $dk_length );
115 #pod
116 #pod The C<verify> function checks that a given derived key (in binary form) matches
117 #pod the password and other parameters provided using a constant-time comparison
118 #pod function.
119 #pod
120 #pod The first parameter is the derived key to check.  The remaining parameters
121 #pod are the same as for L</derive>.
122 #pod
123 #pod =cut
124
125 sub verify {
126     my ( $dk1, @derive_args ) = @_;
127
128     my $dk2 = derive(@derive_args);
129
130     # shortcut if input dk is the wrong length entirely; this is not
131     # constant time, but this doesn't really give much away as
132     # the keys are of different types anyway
133
134     return unless length($dk1) == length($dk2);
135
136     # if lengths match, do constant time comparison to avoid timing attacks
137     my $match = 1;
138     for my $i ( 0 .. length($dk1) - 1 ) {
139         $match &= ( substr( $dk1, $i, 1 ) eq substr( $dk2, $i, 1 ) ) ? 1 : 0;
140     }
141
142     return $match;
143 }
144
145 #pod =func verify_hex
146 #pod
147 #pod Works just like L</verify> but the derived key must be a hex string (without a
148 #pod leading "0x").
149 #pod
150 #pod =cut
151
152 sub verify_hex {
153     my $dk = pack( "H*", shift );
154     return verify( $dk, @_ );
155 }
156
157 #pod =func digest_fcn
158 #pod
159 #pod     ($fcn, $block_size, $digest_length) = digest_fcn('SHA-1');
160 #pod     $digest = $fcn->($data);
161 #pod
162 #pod This function is used internally by PBKDF2::Tiny, but made available in case
163 #pod it's useful to someone.
164 #pod
165 #pod Given one of the valid digest types, it returns a function reference that
166 #pod digests a string of data. It also returns block size and digest length for that
167 #pod digest type.
168 #pod
169 #pod =cut
170
171 sub digest_fcn {
172     my ($type) = @_;
173
174     Carp::croak("Digest function '$type' not supported")
175       unless exists $DIGEST_TYPES{$type};
176
177     return @{ $DIGEST_TYPES{$type} };
178 }
179
180 #pod =func hmac
181 #pod
182 #pod     $key = $digest_fcn->($key) if length($key) > $block_size;
183 #pod     $hmac = hmac( $data, $key, $digest_fcn, $block_size );
184 #pod
185 #pod This function is used internally by PBKDF2::Tiny, but made available in case
186 #pod it's useful to someone.
187 #pod
188 #pod The first two arguments are the data and key inputs to the HMAC function.  Both
189 #pod should be encoded as octet strings, as underlying HMAC/digest functions may
190 #pod croak or may give unexpected results if Perl's internal UTF-8 flag is on.
191 #pod
192 #pod B<Note>: if the key is longer than the digest block size, it must be
193 #pod preprocessed using the digesting function.
194 #pod
195 #pod The third and fourth arguments must be a digesting code reference (from
196 #pod L</digest_fcn>) and block size.
197 #pod
198 #pod =cut
199
200 # hmac function adapted from Digest::HMAC by Graham Barr and Gisle Aas.
201 # Compared to that implementation, this *requires* a preprocessed
202 # key and block size, which makes iterative hmac slightly more efficient.
203 sub hmac {
204     my ( $data, $key, $digest_func, $block_size ) = @_;
205
206     my $k_ipad = $key ^ ( chr(0x36) x $block_size );
207     my $k_opad = $key ^ ( chr(0x5c) x $block_size );
208
209     &$digest_func( $k_opad, &$digest_func( $k_ipad, $data ) );
210 }
211
212 1;
213
214
215 # vim: ts=4 sts=4 sw=4 et:
216
217 __END__
218
219 =pod
220
221 =encoding UTF-8
222
223 =head1 NAME
224
225 PBKDF2::Tiny - Minimalist PBKDF2 (RFC 2898) with HMAC-SHA1 or HMAC-SHA2
226
227 =head1 VERSION
228
229 version 0.005
230
231 =head1 SYNOPSIS
232
233     use PBKDF2::Tiny qw/derive verify/;
234
235     my $dk = derive( 'SHA-1', $pass, $salt, $iters );
236
237     if ( verify( $dk, 'SHA-1', $pass, $salt, $iters ) ) {
238         # password is correct
239     }
240
241 =head1 DESCRIPTION
242
243 This module provides an L<RFC 2898|https://tools.ietf.org/html/rfc2898>
244 compliant PBKDF2 implementation using HMAC-SHA1 or HMAC-SHA2 in under 100 lines
245 of code.  If you are using Perl 5.10 or later, it uses only core Perl modules.
246 If you are on an earlier version of Perl, you need L<Digest::SHA> or
247 L<Digest::SHA::PurePerl>.
248
249 All documented functions are optionally exported.  No functions are exported by default.
250
251 =head1 FUNCTIONS
252
253 =head2 derive
254
255     $dk = derive( $type, $password, $salt, $iterations, $dk_length )
256
257 The C<derive> function outputs a binary string with the derived key.
258 The first argument indicates the digest function to use.  It must be one
259 of: SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512.
260
261 If a password or salt are not provided, they default to the empty string, so
262 don't do that!  L<RFC 2898
263 recommends|https://tools.ietf.org/html/rfc2898#section-4.1> a random salt of at
264 least 8 octets.  If you need a cryptographically strong salt, consider
265 L<Crypt::URandom>.
266
267 The password and salt should encoded as octet strings. If not (i.e. if
268 Perl's internal 'UTF8' flag is on), then an exception will be thrown.
269
270 The number of iterations defaults to 1000 if not provided.  If the derived
271 key length is not provided, it defaults to the output size of the digest
272 function.
273
274 =head2 derive_hex
275
276 Works just like L</derive> but outputs a hex string.
277
278 =head2 verify
279
280     $bool = verify( $dk, $type, $password, $salt, $iterations, $dk_length );
281
282 The C<verify> function checks that a given derived key (in binary form) matches
283 the password and other parameters provided using a constant-time comparison
284 function.
285
286 The first parameter is the derived key to check.  The remaining parameters
287 are the same as for L</derive>.
288
289 =head2 verify_hex
290
291 Works just like L</verify> but the derived key must be a hex string (without a
292 leading "0x").
293
294 =head2 digest_fcn
295
296     ($fcn, $block_size, $digest_length) = digest_fcn('SHA-1');
297     $digest = $fcn->($data);
298
299 This function is used internally by PBKDF2::Tiny, but made available in case
300 it's useful to someone.
301
302 Given one of the valid digest types, it returns a function reference that
303 digests a string of data. It also returns block size and digest length for that
304 digest type.
305
306 =head2 hmac
307
308     $key = $digest_fcn->($key) if length($key) > $block_size;
309     $hmac = hmac( $data, $key, $digest_fcn, $block_size );
310
311 This function is used internally by PBKDF2::Tiny, but made available in case
312 it's useful to someone.
313
314 The first two arguments are the data and key inputs to the HMAC function.  Both
315 should be encoded as octet strings, as underlying HMAC/digest functions may
316 croak or may give unexpected results if Perl's internal UTF-8 flag is on.
317
318 B<Note>: if the key is longer than the digest block size, it must be
319 preprocessed using the digesting function.
320
321 The third and fourth arguments must be a digesting code reference (from
322 L</digest_fcn>) and block size.
323
324 =begin Pod::Coverage
325
326
327
328
329 =end Pod::Coverage
330
331 =head1 SEE ALSO
332
333 =over 4
334
335 =item *
336
337 L<Crypt::PBKDF2>
338
339 =item *
340
341 L<Digest::PBDKF2>
342
343 =back
344
345 =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
346
347 =head1 SUPPORT
348
349 =head2 Bugs / Feature Requests
350
351 Please report any bugs or feature requests through the issue tracker
352 at L<https://github.com/dagolden/PBKDF2-Tiny/issues>.
353 You will be notified automatically of any progress on your issue.
354
355 =head2 Source Code
356
357 This is open source software.  The code repository is available for
358 public review and contribution under the terms of the license.
359
360 L<https://github.com/dagolden/PBKDF2-Tiny>
361
362   git clone https://github.com/dagolden/PBKDF2-Tiny.git
363
364 =head1 AUTHOR
365
366 David Golden <dagolden@cpan.org>
367
368 =head1 COPYRIGHT AND LICENSE
369
370 This software is Copyright (c) 2014 by David Golden.
371
372 This is free software, licensed under:
373
374   The Apache License, Version 2.0, January 2004
375
376 =cut