From 3d7ff31d79b6b96e489409604fdde675975a6d75 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 16 2020 11:46:25 +0000 Subject: perl-Digest-HMAC-1.03 base --- diff --git a/Changes b/Changes new file mode 100644 index 0000000..bc48cad --- /dev/null +++ b/Changes @@ -0,0 +1,24 @@ +2011-07-25 Gisle Aas + + Release 1.03 + + Depend on Digest::SHA instead of Digest::SHA1 [RT#69776] + + Document the blocksize argument [RT#14551] + + + +2010-01-10 Gisle Aas + + Release 1.02 + + Give the distribution a META.yml file + + + +2000-03-13 Gisle Aas + + Release 1.01 + + Broken out of the Digest-MD5-2.12 distribution and made into + a separate dist. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..5db4f40 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,9 @@ +Changes +MANIFEST +Makefile.PL +README +lib/Digest/HMAC.pm +lib/Digest/HMAC_MD5.pm +lib/Digest/HMAC_SHA1.pm +t/rfc2202.t +META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..61c2dda --- /dev/null +++ b/META.yml @@ -0,0 +1,24 @@ +--- #YAML:1.0 +name: Digest-HMAC +version: 1.03 +abstract: Keyed-Hashing for Message Authentication +author: + - Gisle Aas +license: perl +distribution_type: module +configure_requires: + ExtUtils::MakeMaker: 0 +build_requires: + ExtUtils::MakeMaker: 0 +requires: + Digest::MD5: 2 + Digest::SHA: 1 + perl: 5.004 +no_index: + directory: + - t + - inc +generated_by: ExtUtils::MakeMaker version 6.57_05 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..27fe608 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,37 @@ +require 5.004; +use ExtUtils::MakeMaker; + +WriteMakefile( + 'NAME' => 'Digest::HMAC', + 'VERSION_FROM' => 'lib/Digest/HMAC.pm', + 'ABSTRACT_FROM' => 'lib/Digest/HMAC.pm', + 'PREREQ_PM' => { 'Digest::MD5' => 2.00, + 'Digest::SHA' => 1.00, + }, + 'AUTHOR' => 'Gisle Aas ', + 'LICENSE' => 'perl', + 'MIN_PERL_VERSION' => 5.004, +); + + +BEGIN { + # compatibility with older versions of MakeMaker + my $developer = -f ".gitignore"; + my %mm_req = ( + LICENCE => 6.31, + META_MERGE => 6.45, + META_ADD => 6.45, + MIN_PERL_VERSION => 6.48, + ); + undef(*WriteMakefile); + *WriteMakefile = sub { + my %arg = @_; + for (keys %mm_req) { + unless (eval { ExtUtils::MakeMaker->VERSION($mm_req{$_}) }) { + warn "$_ $@" if $developer; + delete $arg{$_}; + } + } + ExtUtils::MakeMaker::WriteMakefile(%arg); + }; +} diff --git a/README b/README new file mode 100644 index 0000000..512665e --- /dev/null +++ b/README @@ -0,0 +1,17 @@ +HMAC is used for message integrity checks between two parties that +share a secret key, and works in combination with some other Digest +algorithm, usually MD5 or SHA-1. The HMAC mechanism is described in +RFC 2104. + +The Digest::HMAC module follow the common Digest:: interface, but the +constructor takes the secret key and the name of some other simple +Digest:: module as argument. + +You will need perl version 5.004 or better to install these modules. +The Digest::MD5 module and Digest::SHA1 module must be installed. + +Copyright 1998-2001 Gisle Aas. +Copyright 1998 Graham Barr. + +This library is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. diff --git a/lib/Digest/HMAC.pm b/lib/Digest/HMAC.pm new file mode 100644 index 0000000..9a164f8 --- /dev/null +++ b/lib/Digest/HMAC.pm @@ -0,0 +1,120 @@ +package Digest::HMAC; +$VERSION = "1.03"; + +use strict; + +# OO interface + +sub new +{ + my($class, $key, $hasher, $block_size) = @_; + $block_size ||= 64; + $key = $hasher->new->add($key)->digest if length($key) > $block_size; + + my $self = bless {}, $class; + $self->{k_ipad} = $key ^ (chr(0x36) x $block_size); + $self->{k_opad} = $key ^ (chr(0x5c) x $block_size); + $self->{hasher} = $hasher->new->add($self->{k_ipad}); + $self; +} + +sub reset +{ + my $self = shift; + $self->{hasher}->reset->add($self->{k_ipad}); + $self; +} + +sub add { my $self = shift; $self->{hasher}->add(@_); $self; } +sub addfile { my $self = shift; $self->{hasher}->addfile(@_); $self; } + +sub _digest +{ + my $self = shift; + my $inner_digest = $self->{hasher}->digest; + $self->{hasher}->reset->add($self->{k_opad}, $inner_digest); +} + +sub digest { shift->_digest->digest; } +sub hexdigest { shift->_digest->hexdigest; } +sub b64digest { shift->_digest->b64digest; } + + +# Functional interface + +require Exporter; +*import = \&Exporter::import; +use vars qw(@EXPORT_OK); +@EXPORT_OK = qw(hmac hmac_hex); + +sub hmac +{ + my($data, $key, $hash_func, $block_size) = @_; + $block_size ||= 64; + $key = &$hash_func($key) if length($key) > $block_size; + + my $k_ipad = $key ^ (chr(0x36) x $block_size); + my $k_opad = $key ^ (chr(0x5c) x $block_size); + + &$hash_func($k_opad, &$hash_func($k_ipad, $data)); +} + +sub hmac_hex { unpack("H*", &hmac); } + +1; + +__END__ + +=head1 NAME + +Digest::HMAC - Keyed-Hashing for Message Authentication + +=head1 SYNOPSIS + + # Functional style + use Digest::HMAC qw(hmac hmac_hex); + $digest = hmac($data, $key, \&myhash); + print hmac_hex($data, $key, \&myhash); + + # OO style + use Digest::HMAC; + $hmac = Digest::HMAC->new($key, "Digest::MyHash"); + + $hmac->add($data); + $hmac->addfile(*FILE); + + $digest = $hmac->digest; + $digest = $hmac->hexdigest; + $digest = $hmac->b64digest; + +=head1 DESCRIPTION + +HMAC is used for message integrity checks between two parties that +share a secret key, and works in combination with some other Digest +algorithm, usually MD5 or SHA-1. The HMAC mechanism is described in +RFC 2104. + +HMAC follow the common C interface, but the constructor +takes the secret key and the name of some other simple C +as argument. + +The hmac() and hmac_hex() functions and the Digest::HMAC->new() constructor +takes an optional $blocksize argument as well. The HMAC algorithm assumes the +digester to hash by iterating a basic compression function on blocks of data +and the $blocksize should match the byte-length of such blocks. + +The default $blocksize is 64 which is suitable for the MD5 and SHA-1 digest +functions. For stronger algorithms the blocksize probably needs to be +increased. + +=head1 SEE ALSO + +L, L + +RFC 2104 + +=head1 AUTHORS + +Graham Barr , Gisle Aas + +=cut diff --git a/lib/Digest/HMAC_MD5.pm b/lib/Digest/HMAC_MD5.pm new file mode 100644 index 0000000..6efa0a1 --- /dev/null +++ b/lib/Digest/HMAC_MD5.pm @@ -0,0 +1,71 @@ +package Digest::HMAC_MD5; +$VERSION="1.01"; + +use strict; +use Digest::MD5 qw(md5); +use Digest::HMAC qw(hmac); + +# OO interface +use vars qw(@ISA); +@ISA=qw(Digest::HMAC); +sub new +{ + my $class = shift; + $class->SUPER::new($_[0], "Digest::MD5", 64); +} + +# Functional interface +require Exporter; +*import = \&Exporter::import; +use vars qw(@EXPORT_OK); +@EXPORT_OK=qw(hmac_md5 hmac_md5_hex); + +sub hmac_md5 +{ + hmac($_[0], $_[1], \&md5, 64); +} + +sub hmac_md5_hex +{ + unpack("H*", &hmac_md5) +} + +1; + +__END__ + +=head1 NAME + +Digest::HMAC_MD5 - Keyed-Hashing for Message Authentication + +=head1 SYNOPSIS + + # Functional style + use Digest::HMAC_MD5 qw(hmac_md5 hmac_md5_hex); + $digest = hmac_md5($data, $key); + print hmac_md5_hex($data, $key); + + # OO style + use Digest::HMAC_MD5; + $hmac = Digest::HMAC_MD5->new($key); + + $hmac->add($data); + $hmac->addfile(*FILE); + + $digest = $hmac->digest; + $digest = $hmac->hexdigest; + $digest = $hmac->b64digest; + +=head1 DESCRIPTION + +This module provide HMAC-MD5 hashing. + +=head1 SEE ALSO + +L, L, L + +=head1 AUTHOR + +Gisle Aas + +=cut diff --git a/lib/Digest/HMAC_SHA1.pm b/lib/Digest/HMAC_SHA1.pm new file mode 100644 index 0000000..c63b00f --- /dev/null +++ b/lib/Digest/HMAC_SHA1.pm @@ -0,0 +1,71 @@ +package Digest::HMAC_SHA1; +$VERSION="1.03"; + +use strict; +use Digest::SHA qw(sha1); +use Digest::HMAC qw(hmac); + +# OO interface +use vars qw(@ISA); +@ISA=qw(Digest::HMAC); +sub new +{ + my $class = shift; + $class->SUPER::new($_[0], "Digest::SHA", 64); # Digest::SHA defaults to SHA-1 +} + +# Functional interface +require Exporter; +*import = \&Exporter::import; +use vars qw(@EXPORT_OK); +@EXPORT_OK=qw(hmac_sha1 hmac_sha1_hex); + +sub hmac_sha1 +{ + hmac($_[0], $_[1], \&sha1, 64); +} + +sub hmac_sha1_hex +{ + unpack("H*", &hmac_sha1) +} + +1; + +__END__ + +=head1 NAME + +Digest::HMAC_SHA1 - Keyed-Hashing for Message Authentication + +=head1 SYNOPSIS + + # Functional style + use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); + $digest = hmac_sha1($data, $key); + print hmac_sha1_hex($data, $key); + + # OO style + use Digest::HMAC_SHA1; + $hmac = Digest::HMAC_SHA1->new($key); + + $hmac->add($data); + $hmac->addfile(*FILE); + + $digest = $hmac->digest; + $digest = $hmac->hexdigest; + $digest = $hmac->b64digest; + +=head1 DESCRIPTION + +This module provide HMAC-SHA-1 hashing. + +=head1 SEE ALSO + +L, L, L + +=head1 AUTHOR + +Gisle Aas + +=cut diff --git a/t/rfc2202.t b/t/rfc2202.t new file mode 100644 index 0000000..ee32767 --- /dev/null +++ b/t/rfc2202.t @@ -0,0 +1,603 @@ +print "1..14\n"; + +$test_case = 0; +$algorithm = ""; + +while () { + next if /^\s+$/; # blank lines + next if /^Cheng & Glenn/; # page header + next if /^RFC 2202/; # page header + chomp; + if (/^2\. Test Cases for/ .. /4\. Security Considerations/) { + if (/^\d+\. Test Cases for (\S+)/) { + if (defined $key) { save($key, $val); undef($key) } + $algorithm = $1; + } elsif (/^(\w+(?:-\w+)*)\s+=\s+(.*)/) { + save($key, $val) if defined $key; + $key = $1; + $val = $2; + $test_case = $val if $key eq "test_case"; + } elsif (/^\s+(.*)/) { + $val .= " $1"; + } elsif (/^4\. /) { + # ignore + } else { + print ">>> $_\n"; + } + } +} +close(DATA); +save($key, $val) if $key; + +sub save +{ + my($key,$val) = @_; + if ($val =~ /^0x(..) repeated (\d+) times$/) { + $val = chr(hex($1)) x $2; + } elsif ($val =~ s/^0x//) { + $val = pack("H*", $val); + } elsif ($val =~ s/^\"// && $val =~ s/\"$//) { + # we already did it + } + $case{$algorithm}[$test_case-1]{$key} = $val; +} + +#use Data::Dumper; print Dumper(\%case); + + +$testno = 0; + +use Digest::HMAC_MD5 qw(hmac_md5); +print "\n# HMAC-MD5 tests\n"; +foreach (@{$case{"HMAC-MD5"}}) { + $testno++; + + # This is a temporary workaround necessitated by a DEC + # compiler bug which breaks the 'x' operator. See + # + # http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-12/msg01720.html + # + if ($^O eq 'dec_osf' and $] < 5.00503) { + require Config; + my $temp=\%Config::Config; # suppress a silly warning + if ($testno =~ /^(?:3|4|6|7)$/ and ! $Config::Config{gccversion}) { + print "ok $testno # skipping test on this platform\n"; + next; + } + } + + #use Data::Dumper; print Dumper($_); + warn unless length($_->{key}) == $_->{key_len}; + warn unless length($_->{data}) == $_->{data_len}; + + my $failed; + # Test OO interface + my $hasher = Digest::HMAC_MD5->new($_->{key}); + $hasher->add($_->{data}); + $failed++ unless $hasher->digest eq $_->{digest}; + + # Test functional interface + $failed++ if hmac_md5($_->{data}, $_->{key}) ne $_->{digest}; + print "not " if $failed; + print "ok $testno\n"; +} + +# Digest::SHA1 might fail if the SHA module is not installed +eval { + # use Digest::HMAC_SHA1 qw(hmac_sha1); + require Digest::HMAC_SHA1; + *hmac_sha1 = \&Digest::HMAC_SHA1::hmac_sha1; +}; +if ($@) { + print "\n# HMAC-SHA-1 tests skipped\n$@\n"; + for (8..14) { print "ok $_\n"; } +} +else { + +print "\n# HMAC-SHA-1 tests\n"; +foreach (@{$case{"HMAC-SHA-1"}}) { + $testno++; + #use Data::Dumper; print Dumper($_); + warn unless length($_->{key}) == $_->{key_len}; + warn unless length($_->{data}) == $_->{data_len}; + + my $failed; + # Test OO interface + my $hasher = Digest::HMAC_SHA1->new($_->{key}); + $hasher->add($_->{data}); + $failed++ unless $hasher->digest eq $_->{digest}; + + # Test functional interface + $failed++ if hmac_sha1($_->{data}, $_->{key}) ne $_->{digest}; + + print "not " if $failed; + print "ok $testno\n"; +} +} + +__END__ + + +Network Working Group P. Cheng +Request for Comments: 2202 IBM +Category: Informational R. Glenn + NIST + September 1997 + + + Test Cases for HMAC-MD5 and HMAC-SHA-1 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +Abstract + + This document provides two sets of test cases for HMAC-MD5 and HMAC- + SHA-1, respectively. HMAC-MD5 and HMAC-SHA-1 are two constructs of + the HMAC [HMAC] message authentication function using the MD5 [MD5] + hash function and the SHA-1 [SHA] hash function. Both constructs are + used by IPSEC [OG,CG] and other protocols to authenticate messages. + The test cases and results provided in this document are meant to be + used as a conformance test for HMAC-MD5 and HMAC-SHA-1 + implementations. + +1. Introduction + + The general method for constructing a HMAC message authentication + function using a particular hash function is described in section 2 + of [HMAC]. We will not repeat the description here. Section 5 of + [HMAC] also discusses truncating the output of HMAC; the rule is that + we should keep the more significant bits (the bits in the left, + assuming a network byte order (big-endian)). + + In sections 2 and 3 we provide test cases for HMAC-MD5 and HMAC-SHA- + 1, respectively. Each case includes the key, the data, and the + result. The values of keys and data are either hexadecimal numbers + (prefixed by "0x") or ASCII character strings in double quotes. If a + value is an ASCII character string, then the HMAC computation for the + corresponding test case DOES NOT include the trailing null character + ('\0') in the string. + + + + + + + + + +Cheng & Glenn Informational [Page 1] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + + The C source code of the functions used to generate HMAC-SHA-1 + results is listed in the Appendix. Note that these functions are + meant to be simple and easy to understand; they are not optimized in + any way. The C source code for computing HMAC-MD5 can be found in + [MD5]; or you can do a simple modification to HMAC-SHA-1 code to get + HMAC-MD5 code, as explained in the Appendix. + + The test cases in this document are cross-verified by three + independent implementations, one from NIST and two from IBM Research. + One IBM implementation uses optimized code that is very different + from the code in the Appendix. An implemenation that concurs with the + results provided in this document should be interoperable with other + similar implemenations. We do not claim that such an implementation + is absolutely correct with respect to the HMAC definition in [HMAC]. + +2. Test Cases for HMAC-MD5 + +test_case = 1 +key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +key_len = 16 +data = "Hi There" +data_len = 8 +digest = 0x9294727a3638bb1c13f48ef8158bfc9d + +test_case = 2 +key = "Jefe" +key_len = 4 +data = "what do ya want for nothing?" +data_len = 28 +digest = 0x750c783e6ab0b503eaa86e310a5db738 + +test_case = 3 +key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +key_len = 16 +data = 0xdd repeated 50 times +data_len = 50 +digest = 0x56be34521d144c88dbb8c733f0e8b3f6 + +test_case = 4 +key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 +key_len = 25 +data = 0xcd repeated 50 times +data_len = 50 +digest = 0x697eaf0aca3a3aea3a75164746ffaa79 + + + + + + + +Cheng & Glenn Informational [Page 2] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + +test_case = 5 +key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +key_len = 16 +data = "Test With Truncation" +data_len = 20 +digest = 0x56461ef2342edc00f9bab995690efd4c +digest-96 = 0x56461ef2342edc00f9bab995 + +test_case = 6 +key = 0xaa repeated 80 times +key_len = 80 +data = "Test Using Larger Than Block-Size Key - Hash Key First" +data_len = 54 +digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd + +test_case = 7 +key = 0xaa repeated 80 times +key_len = 80 +data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" +data_len = 73 +digest = 0x6f630fad67cda0ee1fb1f562db3aa53e + +3. Test Cases for HMAC-SHA-1 + +test_case = 1 +key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +key_len = 20 +data = "Hi There" +data_len = 8 +digest = 0xb617318655057264e28bc0b6fb378c8ef146be00 + +test_case = 2 +key = "Jefe" +key_len = 4 +data = "what do ya want for nothing?" +data_len = 28 +digest = 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79 + +test_case = 3 +key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +key_len = 20 +data = 0xdd repeated 50 times +data_len = 50 +digest = 0x125d7342b9ac11cd91a39af48aa17b4f63f175d3 + + + + + + +Cheng & Glenn Informational [Page 3] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + +test_case = 4 +key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 +key_len = 25 +data = 0xcd repeated 50 times +data_len = 50 +digest = 0x4c9007f4026250c6bc8414f9bf50c86c2d7235da + +test_case = 5 +key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +key_len = 20 +data = "Test With Truncation" +data_len = 20 +digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 +digest-96 = 0x4c1a03424b55e07fe7f27be1 + +test_case = 6 +key = 0xaa repeated 80 times +key_len = 80 +data = "Test Using Larger Than Block-Size Key - Hash Key First" +data_len = 54 +digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 + +test_case = 7 +key = 0xaa repeated 80 times +key_len = 80 +data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" +data_len = 73 +digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 + + + + +Cheng & Glenn Informational [Page 4] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + +4. Security Considerations + + This docuemnt raises no security issues. Discussion on the strength + of the HMAC construction can be found in [HMAC]. + +References + + [HMAC] Krawczyk, H., Bellare, M., and R. Canetti, + "HMAC: Keyed-Hashing for Message Authentication", + RFC 2104, February 1997. + + [MD5] Rivest, R., "The MD5 Message-Digest Algorithm", + RFC 1321, April 1992. + + [SHA] NIST, FIPS PUB 180-1: Secure Hash Standard, April 1995. + + [OG] Oehler, M., and R. Glenn, + "HMAC-MD5 IP Authentication with Replay Prevention", + RFC 2085, February 1997. + + [CG] Chang, S., and R. Glenn, + "HMAC-SHA IP Authentication with Replay Prevention", + Work in Progress. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cheng & Glenn Informational [Page 5] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + +Authors' Addresses + + Pau-Chen Cheng + IBM T.J. Watson Research Center + P.O.Box 704 + Yorktown Heights, NY 10598 + + EMail: pau@watson.ibm.com + + + Robert Glenn + NIST + Building 820, Room 455 + Gaithersburg, MD 20899 + + EMail: rob.glenn@nist.gov + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cheng & Glenn Informational [Page 6] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + +Appendix + + This appendix contains the C reference code which implements HMAC- + SHA-1 using an existing SHA-1 library. It assumes that the SHA-1 + library has similar API's as those of the MD5 code described in RFC + 1321. The code for HMAC-MD5 is similar, just replace the strings + "SHA" and "sha" with "MD5" and "md5". HMAC-MD5 code is also listed in + RFC 2104. + + #ifndef SHA_DIGESTSIZE + #define SHA_DIGESTSIZE 20 + #endif + + #ifndef SHA_BLOCKSIZE + #define SHA_BLOCKSIZE 64 + #endif + + #ifndef MD5_DIGESTSIZE + #define MD5_DIGESTSIZE 16 + #endif + + #ifndef MD5_BLOCKSIZE + #define MD5_BLOCKSIZE 64 + #endif + + /* Function to print the digest */ + void + pr_sha(FILE* fp, char* s, int t) + { + int i ; + + fprintf(fp, "0x") ; + for (i = 0 ; i < t ; i++) + fprintf(fp, "%02x", s[i]) ; + fprintf(fp, "0) ; + } + + void truncate + ( + char* d1, /* data to be truncated */ + char* d2, /* truncated data */ + int len /* length in bytes to keep */ + ) + { + int i ; + for (i = 0 ; i < len ; i++) d2[i] = d1[i]; + } + + + + +Cheng & Glenn Informational [Page 7] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + + /* Function to compute the digest */ + void + hmac_sha + ( + char* k, /* secret key */ + int lk, /* length of the key in bytes */ + char* d, /* data */ + int ld, /* length of data in bytes */ + char* out, /* output buffer, at least "t" bytes */ + int t + ) + { + SHA_CTX ictx, octx ; + char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ; + char key[SHA_DIGESTSIZE] ; + char buf[SHA_BLOCKSIZE] ; + int i ; + + if (lk > SHA_BLOCKSIZE) { + + SHA_CTX tctx ; + + SHAInit(&tctx) ; + SHAUpdate(&tctx, k, lk) ; + SHAFinal(key, &tctx) ; + + k = key ; + lk = SHA_DIGESTSIZE ; + } + + /**** Inner Digest ****/ + + SHAInit(&ictx) ; + + /* Pad the key for inner digest */ + for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x36 ; + for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x36 ; + + SHAUpdate(&ictx, buf, SHA_BLOCKSIZE) ; + SHAUpdate(&ictx, d, ld) ; + + SHAFinal(isha, &ictx) ; + + /**** Outter Digest ****/ + + SHAInit(&octx) ; + + /* Pad the key for outter digest */ + + + +Cheng & Glenn Informational [Page 8] + +RFC 2202 Test Cases for HMAC-MD5 and HMAC-SHA-1 September 1997 + + + for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ; + for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ; + + SHAUpdate(&octx, buf, SHA_BLOCKSIZE) ; + SHAUpdate(&octx, isha, SHA_DIGESTSIZE) ; + + SHAFinal(osha, &octx) ; + + /* truncate and print the results */ + t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t ; + truncate(osha, out, t) ; + pr_sha(stdout, out, t) ; + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cheng & Glenn Informational [Page 9] +