]>
git.saurik.com Git - apple/security.git/blob - Security/libsecurity_utilities/lib/hashing.h
2 * Copyright (c) 2005-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
30 #include <CommonCrypto/CommonDigest.h>
33 #include <sys/types.h>
34 #include <CommonCrypto/CommonDigestSPI.h> // SPI slated to become API
40 // An unconditional base class for all hash objects.
41 // Not much in here; there's no point in declaring one yourself.
45 typedef unsigned char Byte
;
50 // Common prefix for all static hashers.
51 // There's no magic here; we're just setting up a regular framework for duck typing.
53 // If you write template code based on "any static hasher", you can directly tap here
54 // (and learn the actual hash in use through the match on _HashType). But note that
55 // a DynamicHash is not a subclass of Hash, though a DynamicHashInstance will be, duck-like.
57 template <uint32_t _size
, class _HashType
>
58 class Hash
: public Hashing
{
59 _HashType
&_self() { return static_cast<_HashType
&>(*this); } // "my real type"
61 static const size_t digestLength
= _size
; // how many bytes in my digest?
62 typedef Byte Digest
[_size
]; // my digest as a Byte array
63 struct SDigest
{ // my digest as a struct
67 SDigest(const Byte
*source
) { ::memcpy(data
, source
, digestLength
); }
68 friend bool operator < (const SDigest
&x
, const SDigest
&y
) // usable as collection key
69 { return ::memcmp(x
.data
, y
.data
, digestLength
) < 0; }
70 bool operator == (const SDigest
&other
) const
71 { return ::memcmp(this->data
, other
.data
, digestLength
) == 0; }
72 bool operator != (const SDigest
&other
) const
73 { return ::memcmp(this->data
, other
.data
, digestLength
) != 0; }
74 bool operator == (const Byte
*other
) const
75 { return ::memcmp(this->data
, other
, digestLength
) == 0; }
76 bool operator != (const Byte
*other
) const
77 { return ::memcmp(this->data
, other
, digestLength
) != 0; }
80 void operator () (const void *data
, size_t length
) // just an alias for update()
81 { _self().update(data
, length
); }
83 void finish(SDigest
&digest
)
84 { _self().finish(digest
.data
); }
86 bool verify(const Byte
*digest
)
87 { Digest d
; _self().finish(d
); return memcmp(d
, digest
, digestLength
) == 0; }
92 // A dynamic switch for digest generators.
93 // This isn't a subclass of Hash (which is static-fast), but it's duck-typed to it.
94 // Note that digestLength is a function here, not a constant. Obviously.
96 class DynamicHash
: public Hashing
{
98 virtual ~DynamicHash();
100 virtual size_t digestLength() const = 0;
101 virtual void update(const void *data
, size_t length
) = 0;
102 virtual void finish(Byte
*digest
) = 0;
104 void operator () (const void *data
, size_t length
)
105 { return this->update(data
, length
); }
107 bool verify(const Byte
*digest
)
108 { Byte d
[this->digestLength()]; this->finish(d
); return memcmp(d
, digest
, this->digestLength()) == 0; }
113 // Make a DynamicHash from a static Hash class.
115 template <class _HashType
>
116 class DynamicHashInstance
: public DynamicHash
, public _HashType
{
118 // (wish we had C++0x already...)
119 DynamicHashInstance() { }
120 template <class Arg1
>
121 DynamicHashInstance(const Arg1
&arg1
) : _HashType(arg1
) { }
122 template <class Arg1
, class Arg2
>
123 DynamicHashInstance(const Arg1
&arg1
, const Arg2
&arg2
) : _HashType(arg1
, arg2
) { }
124 template <class Arg1
, class Arg2
, class Arg3
>
125 DynamicHashInstance(const Arg1
&arg1
, const Arg2
&arg2
, const Arg3
&arg3
) : _HashType(arg1
, arg2
, arg3
) { }
127 size_t digestLength() const
128 { return _HashType::digestLength
; }
129 void update(const void *data
, size_t length
)
130 { return _HashType::update(data
, length
); }
131 void finish(unsigned char *digest
)
132 { return _HashType::finish(digest
); }
137 // Make a DynamicHash from a CommonCrypto hash algorithm identifier
139 class CCHashInstance
: public DynamicHash
{
141 CCHashInstance(CCDigestAlg alg
);
143 { CCDigestDestroy(mDigest
); }
145 size_t digestLength() const
146 { return CCDigestOutputSize(mDigest
); }
147 void update(const void *data
, size_t length
)
148 { CCDigestUpdate(mDigest
, data
, length
); }
149 void finish(unsigned char *digest
)
150 { CCDigestFinal(mDigest
, digest
); }
158 // A shorthand for holding a DynamicHash subclass we got from some
159 // object out there by asking nicely (by default, calling its getHash() method).
161 template <class _Giver
, DynamicHash
*(_Giver::*_fetcher
)() const = &_Giver::getHash
>
162 class MakeHash
: public std::auto_ptr
<DynamicHash
> {
164 MakeHash(const _Giver
*giver
) : std::auto_ptr
<DynamicHash
>((giver
->*_fetcher
)()) { }
166 operator DynamicHash
*() const { return this->get(); }
171 // A concrete SHA1 class, used in a very many different places.
172 // Note that its digestLength is a constant (not a function).
174 class SHA1
: public CC_SHA1_CTX
, public Hash
<CC_SHA1_DIGEST_LENGTH
, SHA1
> {
176 SHA1() { CC_SHA1_Init(this); }
177 void update(const void *data
, size_t length
)
178 { CC_SHA1_Update(this, data
, (CC_LONG
)length
); }
179 void finish(Byte
*digest
) { CC_SHA1_Final(digest
, this); }
180 using Hash
<CC_SHA1_DIGEST_LENGTH
, SHA1
>::finish
;