2
Copyright (C) 2000-2007 MySQL AB
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; version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; see the file COPYING. If not, write to the
15
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19
/* hash.cpp implements a base for digest types
22
#include "runtime.hpp"
32
HASHwithTransform::HASHwithTransform(word32 digSz, word32 buffSz)
34
assert(digSz <= MaxDigestSz);
35
assert(buffSz <= MaxBufferSz);
39
void HASHwithTransform::AddLength(word32 len)
41
HashLengthType tmp = loLen_;
42
if ( (loLen_ += len) < tmp)
43
hiLen_++; // carry low to high
44
hiLen_ += SafeRightShift<8*sizeof(HashLengthType)>(len);
48
// Update digest with data of size len, do in blocks
49
void HASHwithTransform::Update(const byte* data, word32 len)
51
// do block size increments
52
word32 blockSz = getBlockSize();
53
byte* local = reinterpret_cast<byte*>(buffer_);
56
word32 add = min(len, blockSz - buffLen_);
57
memcpy(&local[buffLen_], data, add);
63
if (buffLen_ == blockSz) {
64
ByteReverseIf(local, local, blockSz, getByteOrder());
73
// Final process, place digest in hash
74
void HASHwithTransform::Final(byte* hash)
76
word32 blockSz = getBlockSize();
77
word32 digestSz = getDigestSize();
78
word32 padSz = getPadSize();
79
ByteOrder order = getByteOrder();
81
AddLength(buffLen_); // before adding pads
82
HashLengthType preLoLen = GetBitCountLo();
83
HashLengthType preHiLen = GetBitCountHi();
84
byte* local = reinterpret_cast<byte*>(buffer_);
86
local[buffLen_++] = 0x80; // add 1
89
if (buffLen_ > padSz) {
90
memset(&local[buffLen_], 0, blockSz - buffLen_);
91
buffLen_ += blockSz - buffLen_;
93
ByteReverseIf(local, local, blockSz, order);
97
memset(&local[buffLen_], 0, padSz - buffLen_);
99
ByteReverseIf(local, local, blockSz, order);
101
memcpy(&local[padSz], order ? &preHiLen : &preLoLen, sizeof(preLoLen));
102
memcpy(&local[padSz+4], order ? &preLoLen : &preHiLen, sizeof(preLoLen));
105
ByteReverseIf(digest_, digest_, digestSz, order);
106
memcpy(hash, digest_, digestSz);
108
Init(); // reset state
112
#ifdef WORD64_AVAILABLE
114
HASH64withTransform::HASH64withTransform(word32 digSz, word32 buffSz)
116
assert(digSz <= MaxDigestSz);
117
assert(buffSz <= MaxBufferSz);
121
void HASH64withTransform::AddLength(word32 len)
123
HashLengthType tmp = loLen_;
124
if ( (loLen_ += len) < tmp)
125
hiLen_++; // carry low to high
126
hiLen_ += SafeRightShift<8*sizeof(HashLengthType)>(len);
130
// Update digest with data of size len, do in blocks
131
void HASH64withTransform::Update(const byte* data, word32 len)
133
// do block size increments
134
word32 blockSz = getBlockSize();
135
byte* local = reinterpret_cast<byte*>(buffer_);
138
word32 add = min(len, blockSz - buffLen_);
139
memcpy(&local[buffLen_], data, add);
145
if (buffLen_ == blockSz) {
146
ByteReverseIf(buffer_, buffer_, blockSz, getByteOrder());
155
// Final process, place digest in hash
156
void HASH64withTransform::Final(byte* hash)
158
word32 blockSz = getBlockSize();
159
word32 digestSz = getDigestSize();
160
word32 padSz = getPadSize();
161
ByteOrder order = getByteOrder();
163
AddLength(buffLen_); // before adding pads
164
HashLengthType preLoLen = GetBitCountLo();
165
HashLengthType preHiLen = GetBitCountHi();
166
byte* local = reinterpret_cast<byte*>(buffer_);
168
local[buffLen_++] = 0x80; // add 1
171
if (buffLen_ > padSz) {
172
memset(&local[buffLen_], 0, blockSz - buffLen_);
173
buffLen_ += blockSz - buffLen_;
175
ByteReverseIf(buffer_, buffer_, blockSz, order);
179
memset(&local[buffLen_], 0, padSz - buffLen_);
181
ByteReverseIf(buffer_, buffer_, padSz, order);
183
buffer_[blockSz / sizeof(word64) - 2] = order ? preHiLen : preLoLen;
184
buffer_[blockSz / sizeof(word64) - 1] = order ? preLoLen : preHiLen;
187
ByteReverseIf(digest_, digest_, digestSz, order);
188
memcpy(hash, digest_, digestSz);
190
Init(); // reset state
193
#endif // WORD64_AVAILABLE