E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

ghash.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file ghash.h
19 ///
20
21 #ifndef G_HASH__H
22 #define G_HASH__H
23
24 #include "gdef.h"
25 #include "gexception.h"
26 #include <string>
27
28 namespace G
29 {
30 class Hash ;
31 }
32
33 /// \class G::Hash
34 /// A class for creating HMACs using an arbitrary cryptographic hash function.
35 ///
36 class G::Hash
37 {
38 public:
39 G_EXCEPTION( InvalidMaskedKey , "invalid hash key" ) ;
40 struct Masked /// An overload discriminator for G::Hash::hmac()
41 {} ;
42
43 template <typename Fn2> static std::string hmac( Fn2 digest , size_t blocksize , const std::string & key ,
44 const std::string & input ) ;
45 ///< Computes a Hashed Message Authentication Code using given hash
46 ///< function. This is typically for challenge-response authentication
47 ///< where the plaintext input is an arbitrary challenge string from the
48 ///< server that the client has to hmac() using their shared private key.
49 ///<
50 ///< See also RFC-2104 [HMAC-MD5].
51 ///<
52 ///< For hash function H with block size B (64) using shared key SK:
53 ///<
54 ///< \code
55 ///< K = large(SK) ? H(SK) : SK
56 ///< ipad = 0x36 repeated B times
57 ///< opad = 0x5C repeated B times
58 ///< HMAC = H( K XOR opad , H( K XOR ipad , plaintext ) )
59 ///< \endcode
60 ///<
61 ///< The H() function processes a stream of blocks; the first parameter
62 ///< above represents the first block, and the second parameter is the
63 ///< rest of the stream (zero-padded up to a block boundary).
64 ///<
65 ///< The shared key can be up to B bytes, or if more than B bytes then
66 ///< K is the L-byte result of hashing the shared-key. K is zero-padded
67 ///< up to B bytes for XOR-ing.
68
69 template <typename Fn2> static std::string hmac( Fn2 postdigest , const std::string & masked_key ,
70 const std::string & input , Masked ) ;
71 ///< An hmac() overload using a masked key.
72
73 template <typename Fn1, typename Fn2> static std::string mask( Fn1 predigest , Fn2 digest ,
74 size_t blocksize , const std::string & shared_key ) ;
75 ///< Computes a masked key from the given shared key, returning a
76 ///< non-printable string. This can be passed to the 'masked' overload
77 ///< of hmac() once the message is known.
78 ///<
79 ///< A masked key (MK) is the result of doing the initial, plaintext-independent
80 ///< parts of HMAC computation, taking the intermediate state of both the
81 ///< inner and outer hash functions.
82 ///<
83 ///< \code
84 ///< K = large(SK) ? H(SK) : SK
85 ///< HKipad = H( K XOR ipad , )
86 ///< HKopad = H( K XOR opad , )
87 ///< MK := ( HKipad , HKopad )
88 ///< \endcode
89
90 static std::string printable( const std::string & input ) ;
91 ///< Converts a binary string into a printable form, using a
92 ///< lowercase hexadecimal encoding.
93
94 private:
95 template <typename Fn2> static std::string keyx( Fn2 , size_t blocksize , std::string k ) ;
96 static std::string xor_( const std::string & s1 , const std::string & s2 ) ;
97 static std::string ipad( size_t blocksize ) ;
98 static std::string opad( size_t blocksize ) ;
99 Hash() ;
100 } ;
101
102 template <typename Fn2>
103 std::string G::Hash::keyx( Fn2 fn , size_t blocksize , std::string k )
104 {
105 if( k.length() > blocksize )
106 k = fn( k , std::string() ) ;
107 if( k.length() < blocksize )
108 k.append( blocksize-k.length() , '\0' ) ;
109 return k ;
110 }
111
112 template <typename Fn2>
113 inline
114 std::string G::Hash::hmac( Fn2 fn , size_t blocksize , const std::string & k , const std::string & input )
115 {
116 const std::string kx = keyx( fn , blocksize , k ) ;
117 return fn( xor_(kx,opad(blocksize)) , fn(xor_(kx,ipad(blocksize)),input) ) ;
118 }
119
120 template <typename Fn, typename Fn2>
121 inline
122 std::string G::Hash::mask( Fn predigest_fn , Fn2 digest_fn , size_t blocksize , const std::string & k )
123 {
124 std::string kx = keyx( digest_fn , blocksize , k ) ;
125 std::string ki_state = predigest_fn( xor_(kx,ipad(blocksize)) ) ;
126 std::string ko_state = predigest_fn( xor_(kx,opad(blocksize)) ) ;
127 return ki_state + ko_state ;
128 }
129
130 template <typename Fn2>
131 inline
132 std::string G::Hash::hmac( Fn2 postdigest_fn , const std::string & masked_key , const std::string & input , Masked )
133 {
134 return postdigest_fn( masked_key , input ) ;
135 }
136
137 #endif
G::Hash::hmac
static std::string hmac(Fn2 digest, size_t blocksize, const std::string &key, const std::string &input)
Computes a Hashed Message Authentication Code using given hash function.
Definition: ghash.h:114
G::Hash::Masked
An overload discriminator for G::Hash::hmac()
Definition: ghash.h:40
G
Low-level classes.
Definition: garg.h:29
G::Hash::printable
static std::string printable(const std::string &input)
Converts a binary string into a printable form, using a lowercase hexadecimal encoding.
Definition: ghash.cpp:53
gexception.h
G::Hash::mask
static std::string mask(Fn1 predigest, Fn2 digest, size_t blocksize, const std::string &shared_key)
Computes a masked key from the given shared key, returning a non-printable string.
G::Hash
A class for creating HMACs using an arbitrary cryptographic hash function.
Definition: ghash.h:36