ObjFW  Check-in [a5006f1d31]

Overview
Comment:OF*Hash: Make use of the new OFSecureData
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a5006f1d31bd389fe748ff079d7c4a1010b216c93868b4128fb454a9ad269efa
User & Date: js on 2018-04-07 20:05:51
Other Links: manifest | tags
Context
2018-04-07
20:18
OFHMAC: Make use of the new OFSecureData check-in: 0e57691b22 user: js tags: trunk
20:05
OF*Hash: Make use of the new OFSecureData check-in: a5006f1d31 user: js tags: trunk
14:13
Add OFSecureData check-in: d4d9072480 user: js tags: trunk
Changes

Modified src/OFMD5Hash.h from [d676855739] to [9ada856280].

15
16
17
18
19
20
21


22
23
24
25
26
27
28


29
30
31
32
33
34
35








36
37
38
39
40
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
41
42
43
44
45







+
+







+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+





 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/*!
 * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h
 *
 * @brief A class which provides methods to create an MD5 hash.
 */
@interface OFMD5Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_md5_hash_ivars {
	uint32_t _state[4];
	uint64_t _bits;
	union of_md5_hash_buffer {
		uint8_t bytes[64];
		uint32_t words[16];
	} _buffer;
	size_t _bufferLength;
		uint32_t state[4];
		uint64_t bits;
		union of_md5_hash_buffer {
			uint8_t bytes[64];
			uint32_t words[16];
		} buffer;
		size_t bufferLength;
	} *_iVars;
	bool _calculated;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFMD5Hash.m from [50d4eb76c2] to [6abd20d9a3].

16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







+


+







 */

#include "config.h"

#include <string.h>

#import "OFMD5Hash.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFOutOfRangeException.h"

@interface OFMD5Hash ()
- (void)of_resetState;
@end

#define F(a, b, c) (((a) & (b)) | (~(a) & (c)))
#define G(a, b, c) (((a) & (c)) | ((b) & ~(c)))
63
64
65
66
67
68
69
70

71
72
73

74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
65
66
67
68
69
70
71

72
73
74

75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91







-
+


-
+








-
+







	7, 12, 17, 22,
	5, 9, 14, 20,
	4, 11, 16, 23,
	6, 10, 15, 21
};

static OF_INLINE void
byteSwapVectorIfBE(uint32_t *vector, uint8_t length)
byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length)
{
#ifdef OF_BIG_ENDIAN
	for (uint8_t i = 0; i < length; i++)
	for (uint_fast8_t i = 0; i < length; i++)
		vector[i] = OF_BSWAP32(vector[i]);
#endif
}

static void
processBlock(uint32_t *state, uint32_t *buffer)
{
	uint32_t new[4];
	uint8_t i = 0;
	uint_fast8_t i = 0;

	new[0] = state[0];
	new[1] = state[1];
	new[2] = state[2];
	new[3] = state[3];

	byteSwapVectorIfBE(buffer, 16);
135
136
137
138
139
140
141





142





143
144
145





146
147
148
149

150
151
152
153
154
155
156

157
158
159

160
161

162
163
164
165
166
167
168
169
170
171
172




173
174
175
176
177
178

179
180
181
182
183



184

185
186
187

188
189
190
191

192
193


194
195
196
197
198
199
200



201
202
203
204
205
206
207
208

209
210
211



212
213
214
215



216
217

218
219



220
221
222
223



224
225
226

227
228
229
230
231
232
233
234



235
236
237
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171

172
173


174


175
176
177
178
179
180
181
182




183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200

201
202
203

204
205
206
207
208
209


210
211
212
213
214
215



216
217
218
219
220
221
222
223
224
225

226
227


228
229
230
231



232
233
234
235
236
237


238
239
240
241



242
243
244
245
246

247
248
249
250
251
252



253
254
255
256
257
258







+
+
+
+
+
-
+
+
+
+
+



+
+
+
+
+



-
+






-
+

-
-
+
-
-
+







-
-
-
-
+
+
+
+





-
+





+
+
+
-
+


-
+




+
-
-
+
+




-
-
-
+
+
+







-
+

-
-
+
+
+

-
-
-
+
+
+


+
-
-
+
+
+

-
-
-
+
+
+


-
+





-
-
-
+
+
+



	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	@try {
		_iVarsData = [[OFSecureData alloc]
		    initWithCount: sizeof(*_iVars)];
		_iVars = [_iVarsData items];

	[self of_resetState];
		[self of_resetState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)of_init
{
	return [super init];
}

- (void)dealloc
{
	[self reset];
	[_iVarsData release];

	[super dealloc];
}

- (id)copy
{
	OFMD5Hash *copy = [[OFMD5Hash alloc] init];
	OFMD5Hash *copy = [[OFMD5Hash alloc] of_init];

	memcpy(copy->_state, _state, sizeof(_state));
	copy->_bits = _bits;
	copy->_iVarsData = [_iVarsData copy];
	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_iVars = [copy->_iVarsData items];
	copy->_calculated = _calculated;

	return copy;
}

- (void)of_resetState
{
	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_iVars->state[0] = 0x67452301;
	_iVars->state[1] = 0xEFCDAB89;
	_iVars->state[2] = 0x98BADCFE;
	_iVars->state[3] = 0x10325476;
}

- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;
	const unsigned char *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	if (length > SIZE_MAX / 8)
		@throw [OFOutOfRangeException exception];

	_bits += (length * 8);
	_iVars->bits += (length * 8);

	while (length > 0) {
		size_t min = 64 - _bufferLength;
		size_t min = 64 - _iVars->bufferLength;

		if (min > length)
			min = length;

		memcpy(_iVars->buffer.bytes + _iVars->bufferLength,
		memcpy(_buffer.bytes + _bufferLength, buffer, min);
		_bufferLength += min;
		    buffer, min);
		_iVars->bufferLength += min;

		buffer += min;
		length -= min;

		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		if (_iVars->bufferLength == 64) {
			processBlock(_iVars->state, _iVars->buffer.words);
			_iVars->bufferLength = 0;
		}
	}
}

- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t *)_state;
		return (const unsigned char *)_iVars->state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);
	_iVars->buffer.bytes[_iVars->bufferLength] = 0x80;
	of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0,
	    64 - _iVars->bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	if (_iVars->bufferLength >= 56) {
		processBlock(_iVars->state, _iVars->buffer.words);
		of_explicit_memset(_iVars->buffer.bytes, 0, 64);
	}

	_iVars->buffer.words[14] =
	_buffer.words[14] = OF_BSWAP32_IF_BE((uint32_t)(_bits & 0xFFFFFFFF));
	_buffer.words[15] = OF_BSWAP32_IF_BE((uint32_t)(_bits >> 32));
	    OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits & 0xFFFFFFFF));
	_iVars->buffer.words[15] =
	    OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits >> 32));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfBE(_state, 4);
	processBlock(_iVars->state, _iVars->buffer.words);
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	byteSwapVectorIfBE(_iVars->state, 4);
	_calculated = true;

	return (const uint8_t *)_state;
	return (const unsigned char *)_iVars->state;
}

- (void)reset
{
	[self of_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_iVars->bits = 0;
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	_iVars->bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFRIPEMD160Hash.h from [98afef74b0] to [ccb72ce63b].

15
16
17
18
19
20
21


22
23
24
25
26
27
28


29
30
31
32
33
34
35








36
37
38
39
40
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
41
42
43
44
45







+
+







+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+





 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/*!
 * @class OFRIPEMD160Hash OFRIPEMD160Hash.h ObjFW/OFRIPEMD160Hash.h
 *
 * @brief A class which provides methods to create a RIPEMD-160 hash.
 */
@interface OFRIPEMD160Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_ripemd160_hash_ivars {
	uint32_t _state[5];
	uint64_t _bits;
	union of_ripemd_160_hash_buffer {
		uint8_t bytes[64];
		uint32_t words[16];
	} _buffer;
	size_t _bufferLength;
		uint32_t state[5];
		uint64_t bits;
		union of_ripemd160_hash_buffer {
			uint8_t bytes[64];
			uint32_t words[16];
		} buffer;
		size_t bufferLength;
	} *_iVars;
	bool _calculated;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFRIPEMD160Hash.m from [b8c35b028c] to [3667f44aa4].

16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







+


+







 */

#include "config.h"

#include <string.h>

#import "OFRIPEMD160Hash.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFOutOfRangeException.h"

@interface OFRIPEMD160Hash ()
- (void)of_resetState;
@end

#define F(a, b, c) ((a) ^ (b) ^ (c))
#define G(a, b, c) (((a) & (b)) | (~(a) & (c)))
59
60
61
62
63
64
65
66

67
68
69

70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
61
62
63
64
65
66
67

68
69
70

71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+


-
+








-
+







	9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
	9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
	15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
	8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
};

static OF_INLINE void
byteSwapVectorIfBE(uint32_t *vector, uint8_t length)
byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length)
{
#ifdef OF_BIG_ENDIAN
	for (uint8_t i = 0; i < length; i++)
	for (uint_fast8_t i = 0; i < length; i++)
		vector[i] = OF_BSWAP32(vector[i]);
#endif
}

static void
processBlock(uint32_t *state, uint32_t *buffer)
{
	uint32_t new[5], new2[5];
	uint8_t i = 0;
	uint_fast8_t i = 0;

	new[0] = new2[0] = state[0];
	new[1] = new2[1] = state[1];
	new[2] = new2[2] = state[2];
	new[3] = new2[3] = state[3];
	new[4] = new2[4] = state[4];

149
150
151
152
153
154
155





156





157
158
159





160
161
162
163

164
165
166
167
168
169
170

171
172
173

174
175

176
177
178
179
180
181
182
183
184
185
186
187





188
189
190
191
192
193

194
195
196
197
198



199

200
201
202

203
204
205
206

207
208


209
210
211
212
213
214
215



216
217
218
219
220
221
222
223

224
225
226



227
228
229
230



231
232

233
234



235
236
237
238



239
240
241

242
243
244
245
246
247
248
249



250
251
252
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185

186
187


188


189
190
191
192
193
194
195
196





197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215

216
217
218

219
220
221
222
223
224


225
226
227
228
229
230



231
232
233
234
235
236
237
238
239
240

241
242


243
244
245
246



247
248
249
250
251
252


253
254
255
256



257
258
259
260
261

262
263
264
265
266
267



268
269
270
271
272
273







+
+
+
+
+
-
+
+
+
+
+



+
+
+
+
+



-
+






-
+

-
-
+
-
-
+







-
-
-
-
-
+
+
+
+
+





-
+





+
+
+
-
+


-
+




+
-
-
+
+




-
-
-
+
+
+







-
+

-
-
+
+
+

-
-
-
+
+
+


+
-
-
+
+
+

-
-
-
+
+
+


-
+





-
-
-
+
+
+



	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	@try {
		_iVarsData = [[OFSecureData alloc]
		    initWithCount: sizeof(*_iVars)];
		_iVars = [_iVarsData items];

	[self of_resetState];
		[self of_resetState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)of_init
{
	return [super init];
}

- (void)dealloc
{
	[self reset];
	[_iVarsData release];

	[super dealloc];
}

- (id)copy
{
	OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] init];
	OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] of_init];

	memcpy(copy->_state, _state, sizeof(_state));
	copy->_bits = _bits;
	copy->_iVarsData = [_iVarsData copy];
	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_iVars = [copy->_iVarsData items];
	copy->_calculated = _calculated;

	return copy;
}

- (void)of_resetState
{
	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_state[4] = 0xC3D2E1F0;
	_iVars->state[0] = 0x67452301;
	_iVars->state[1] = 0xEFCDAB89;
	_iVars->state[2] = 0x98BADCFE;
	_iVars->state[3] = 0x10325476;
	_iVars->state[4] = 0xC3D2E1F0;
}

- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;
	const unsigned char *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	if (length > SIZE_MAX / 8)
		@throw [OFOutOfRangeException exception];

	_bits += (length * 8);
	_iVars->bits += (length * 8);

	while (length > 0) {
		size_t min = 64 - _bufferLength;
		size_t min = 64 - _iVars->bufferLength;

		if (min > length)
			min = length;

		memcpy(_iVars->buffer.bytes + _iVars->bufferLength,
		memcpy(_buffer.bytes + _bufferLength, buffer, min);
		_bufferLength += min;
		    buffer, min);
		_iVars->bufferLength += min;

		buffer += min;
		length -= min;

		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		if (_iVars->bufferLength == 64) {
			processBlock(_iVars->state, _iVars->buffer.words);
			_iVars->bufferLength = 0;
		}
	}
}

- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t *)_state;
		return (const unsigned char *)_iVars->state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);
	_iVars->buffer.bytes[_iVars->bufferLength] = 0x80;
	of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0,
	    64 - _iVars->bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	if (_iVars->bufferLength >= 56) {
		processBlock(_iVars->state, _iVars->buffer.words);
		of_explicit_memset(_iVars->buffer.bytes, 0, 64);
	}

	_iVars->buffer.words[14] =
	_buffer.words[14] = OF_BSWAP32_IF_BE((uint32_t)(_bits & 0xFFFFFFFF));
	_buffer.words[15] = OF_BSWAP32_IF_BE((uint32_t)(_bits >> 32));
	    OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits & 0xFFFFFFFF));
	_iVars->buffer.words[15] =
	    OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits >> 32));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfBE(_state, 5);
	processBlock(_iVars->state, _iVars->buffer.words);
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	byteSwapVectorIfBE(_iVars->state, 5);
	_calculated = true;

	return (const uint8_t *)_state;
	return (const unsigned char *)_iVars->state;
}

- (void)reset
{
	[self of_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_iVars->bits = 0;
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	_iVars->bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFSHA1Hash.h from [85500252f6] to [36c94fd571].

15
16
17
18
19
20
21


22
23
24
25
26
27
28


29
30
31
32
33
34
35








36
37
38
39
40
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
41
42
43
44
45







+
+







+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+





 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/*!
 * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h
 *
 * @brief A class which provides methods to create an SHA-1 hash.
 */
@interface OFSHA1Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_sha1_hash_ivars {
	uint32_t _state[5];
	uint64_t _bits;
	union of_sha_1_hash_buffer {
		uint8_t bytes[64];
		uint32_t words[80];
	} _buffer;
	size_t _bufferLength;
		uint32_t state[5];
		uint64_t bits;
		union of_sha1_hash_buffer {
			uint8_t bytes[64];
			uint32_t words[80];
		} buffer;
		size_t bufferLength;
	} *_iVars;
	bool _calculated;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFSHA1Hash.m from [a46dde114c] to [d4e11eaa57].

16
17
18
19
20
21
22

23
24

25
26
27
28
29
30
31
32
33
34
35
36

37
38
39

40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40

41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







+


+











-
+


-
+








-
+







 */

#include "config.h"

#include <string.h>

#import "OFSHA1Hash.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFOutOfRangeException.h"

@interface OFSHA1Hash ()
- (void)of_resetState;
@end

#define F(a, b, c, d) ((d) ^ ((b) & ((c) ^ (d))))
#define G(a, b, c, d) ((b) ^ (c) ^ (d))
#define H(a, b, c, d) (((b) & (c)) | ((d) & ((b) | (c))))
#define I(a, b, c, d) ((b) ^ (c) ^ (d))

static OF_INLINE void
byteSwapVectorIfLE(uint32_t *vector, uint8_t length)
byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length)
{
#ifndef OF_BIG_ENDIAN
	for (uint8_t i = 0; i < length; i++)
	for (uint_fast8_t i = 0; i < length; i++)
		vector[i] = OF_BSWAP32(vector[i]);
#endif
}

static void
processBlock(uint32_t *state, uint32_t *buffer)
{
	uint32_t new[5];
	uint8_t i;
	uint_fast8_t i;

	new[0] = state[0];
	new[1] = state[1];
	new[2] = state[2];
	new[3] = state[3];
	new[4] = state[4];

109
110
111
112
113
114
115





116





117
118
119





120
121
122
123

124
125
126
127
128
129
130

131
132
133

134
135

136
137
138
139
140
141
142
143
144
145
146
147





148
149
150
151
152
153

154
155
156
157
158



159

160
161
162

163
164
165
166

167
168


169
170
171
172
173
174
175



176
177
178
179
180
181
182
183

184
185
186



187
188
189
190



191
192

193
194



195
196
197
198



199
200
201

202
203
204
205
206
207
208
209



210
211
212
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145

146
147


148


149
150
151
152
153
154
155
156





157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175

176
177
178

179
180
181
182
183
184


185
186
187
188
189
190



191
192
193
194
195
196
197
198
199
200

201
202


203
204
205
206



207
208
209
210
211
212


213
214
215
216



217
218
219
220
221

222
223
224
225
226
227



228
229
230
231
232
233







+
+
+
+
+
-
+
+
+
+
+



+
+
+
+
+



-
+






-
+

-
-
+
-
-
+







-
-
-
-
-
+
+
+
+
+





-
+





+
+
+
-
+


-
+




+
-
-
+
+




-
-
-
+
+
+







-
+

-
-
+
+
+

-
-
-
+
+
+


+
-
-
+
+
+

-
-
-
+
+
+


-
+





-
-
-
+
+
+



	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	@try {
		_iVarsData = [[OFSecureData alloc]
		    initWithCount: sizeof(*_iVars)];
		_iVars = [_iVarsData items];

	[self of_resetState];
		[self of_resetState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)of_init
{
	return [super init];
}

- (void)dealloc
{
	[self reset];
	[_iVarsData release];

	[super dealloc];
}

- (id)copy
{
	OFSHA1Hash *copy = [[OFSHA1Hash alloc] init];
	OFSHA1Hash *copy = [[OFSHA1Hash alloc] of_init];

	memcpy(copy->_state, _state, sizeof(_state));
	copy->_bits = _bits;
	copy->_iVarsData = [_iVarsData copy];
	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_iVars = [copy->_iVarsData items];
	copy->_calculated = _calculated;

	return copy;
}

- (void)of_resetState
{
	_state[0] = 0x67452301;
	_state[1] = 0xEFCDAB89;
	_state[2] = 0x98BADCFE;
	_state[3] = 0x10325476;
	_state[4] = 0xC3D2E1F0;
	_iVars->state[0] = 0x67452301;
	_iVars->state[1] = 0xEFCDAB89;
	_iVars->state[2] = 0x98BADCFE;
	_iVars->state[3] = 0x10325476;
	_iVars->state[4] = 0xC3D2E1F0;
}

- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;
	const unsigned char *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	if (length > SIZE_MAX / 8)
		@throw [OFOutOfRangeException exception];

	_bits += (length * 8);
	_iVars->bits += (length * 8);

	while (length > 0) {
		size_t min = 64 - _bufferLength;
		size_t min = 64 - _iVars->bufferLength;

		if (min > length)
			min = length;

		memcpy(_iVars->buffer.bytes + _iVars->bufferLength,
		memcpy(_buffer.bytes + _bufferLength, buffer, min);
		_bufferLength += min;
		    buffer, min);
		_iVars->bufferLength += min;

		buffer += min;
		length -= min;

		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		if (_iVars->bufferLength == 64) {
			processBlock(_iVars->state, _iVars->buffer.words);
			_iVars->bufferLength = 0;
		}
	}
}

- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t *)_state;
		return (const unsigned char *)_iVars->state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);
	_iVars->buffer.bytes[_iVars->bufferLength] = 0x80;
	of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0,
	    64 - _iVars->bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	if (_iVars->bufferLength >= 56) {
		processBlock(_iVars->state, _iVars->buffer.words);
		of_explicit_memset(_iVars->buffer.bytes, 0, 64);
	}

	_iVars->buffer.words[14] =
	_buffer.words[14] = OF_BSWAP32_IF_LE((uint32_t)(_bits >> 32));
	_buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF));
	    OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits >> 32));
	_iVars->buffer.words[15] =
	    OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits & 0xFFFFFFFF));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 5);
	processBlock(_iVars->state, _iVars->buffer.words);
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	byteSwapVectorIfLE(_iVars->state, 5);
	_calculated = true;

	return (const uint8_t *)_state;
	return (const unsigned char *)_iVars->state;
}

- (void)reset
{
	[self of_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_iVars->bits = 0;
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	_iVars->bufferLength = 0;
	_calculated = false;
}
@end

Modified src/OFSHA224Hash.m from [bbd5eceb49] to [1e83b08201].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








38
39
23
24
25
26
27
28
29








30
31
32
33
34
35
36
37
38
39







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


+ (size_t)digestSize
{
	return 28;
}

- (void)of_resetState
{
	_state[0] = 0xC1059ED8;
	_state[1] = 0x367CD507;
	_state[2] = 0x3070DD17;
	_state[3] = 0xF70E5939;
	_state[4] = 0xFFC00B31;
	_state[5] = 0x68581511;
	_state[6] = 0x64F98FA7;
	_state[7] = 0xBEFA4FA4;
	_iVars->state[0] = 0xC1059ED8;
	_iVars->state[1] = 0x367CD507;
	_iVars->state[2] = 0x3070DD17;
	_iVars->state[3] = 0xF70E5939;
	_iVars->state[4] = 0xFFC00B31;
	_iVars->state[5] = 0x68581511;
	_iVars->state[6] = 0x64F98FA7;
	_iVars->state[7] = 0xBEFA4FA4;
}
@end

Modified src/OFSHA224Or256Hash.h from [47eff0e7f8] to [ff3ca7c0af].

15
16
17
18
19
20
21


22
23
24
25
26
27
28


29
30
31
32
33
34
35








36
37
38
39
40
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
41
42
43
44
45







+
+







+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+





 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/*!
 * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h
 *
 * @brief A base class for SHA-224 and SHA-256.
 */
@interface OFSHA224Or256Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_sha224_or_256_hash_ivars {
	uint32_t _state[8];
	uint64_t _bits;
	union of_sha_224_or_256_hash_buffer {
		uint8_t bytes[64];
		uint32_t words[64];
	} _buffer;
	size_t _bufferLength;
		uint32_t state[8];
		uint64_t bits;
		union of_sha224_or_256_hash_buffer {
			uint8_t bytes[64];
			uint32_t words[64];
		} buffer;
		size_t bufferLength;
	} *_iVars;
	bool _calculated;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFSHA224Or256Hash.m from [2d148c64a2] to [31a535c436].

17
18
19
20
21
22
23

24
25

26
27
28
29
30
31
32
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34







+


+








#include "config.h"

#include <stdlib.h>
#include <string.h>

#import "OFSHA224Or256Hash.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFOutOfRangeException.h"

@interface OFSHA224Or256Hash ()
- (void)of_resetState;
@end

static const uint32_t table[] = {
	0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
44
45
46
47
48
49
50
51

52
53
54

55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
46
47
48
49
50
51
52

53
54
55

56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+


-
+








-
+







	0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
	0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
	0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
	0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};

static OF_INLINE void
byteSwapVectorIfLE(uint32_t *vector, uint8_t length)
byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length)
{
#ifndef OF_BIG_ENDIAN
	for (uint8_t i = 0; i < length; i++)
	for (uint_fast8_t i = 0; i < length; i++)
		vector[i] = OF_BSWAP32(vector[i]);
#endif
}

static void
processBlock(uint32_t *state, uint32_t *buffer)
{
	uint32_t new[8];
	uint8_t i;
	uint_fast8_t i;

	new[0] = state[0];
	new[1] = state[1];
	new[2] = state[2];
	new[3] = state[3];
	new[4] = state[4];
	new[5] = state[5];
132
133
134
135
136
137
138




139
140
141
142
143
144
145
146
147
148
149
150
151





152
153
154
155

156
157
158
159
160
161
162

163
164
165

166
167

168
169
170
171
172
173
174
175
176

177
178
179
180
181



182

183
184
185

186
187
188
189

190
191


192
193
194
195
196
197
198



199
200
201
202
203
204
205
206

207
208
209



210
211
212
213



214
215

216
217



218
219
220
221



222
223
224

225
226
227
228
229
230
231
232



233
234
235
236
237
238
239
240
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172

173
174


175


176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193

194
195
196

197
198
199
200
201
202


203
204
205
206
207
208



209
210
211
212
213
214
215
216
217
218

219
220


221
222
223
224



225
226
227
228
229
230


231
232
233
234



235
236
237
238
239

240
241
242
243
244
245



246
247
248
249
250
251
252
253
254
255
256







+
+
+
+













+
+
+
+
+



-
+






-
+

-
-
+
-
-
+








-
+





+
+
+
-
+


-
+




+
-
-
+
+




-
-
-
+
+
+







-
+

-
-
+
+
+

-
-
-
+
+
+


+
-
-
+
+
+

-
-
-
+
+
+


-
+





-
-
-
+
+
+








}

- (instancetype)init
{
	self = [super init];

	@try {
		_iVarsData = [[OFSecureData alloc]
		    initWithCount: sizeof(*_iVars)];
		_iVars = [_iVarsData items];

		if ([self class] == [OFSHA224Or256Hash class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		[self of_resetState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)of_init
{
	return [super init];
}

- (void)dealloc
{
	[self reset];
	[_iVarsData release];

	[super dealloc];
}

- (id)copy
{
	OFSHA224Or256Hash *copy = [[[self class] alloc] init];
	OFSHA224Or256Hash *copy = [[[self class] alloc] of_init];

	memcpy(copy->_state, _state, sizeof(_state));
	copy->_bits = _bits;
	copy->_iVarsData = [_iVarsData copy];
	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_iVars = [copy->_iVarsData items];
	copy->_calculated = _calculated;

	return copy;
}

- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;
	const unsigned char *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	if (length > SIZE_MAX / 8)
		@throw [OFOutOfRangeException exception];

	_bits += (length * 8);
	_iVars->bits += (length * 8);

	while (length > 0) {
		size_t min = 64 - _bufferLength;
		size_t min = 64 - _iVars->bufferLength;

		if (min > length)
			min = length;

		memcpy(_iVars->buffer.bytes + _iVars->bufferLength,
		memcpy(_buffer.bytes + _bufferLength, buffer, min);
		_bufferLength += min;
		    buffer, min);
		_iVars->bufferLength += min;

		buffer += min;
		length -= min;

		if (_bufferLength == 64) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		if (_iVars->bufferLength == 64) {
			processBlock(_iVars->state, _iVars->buffer.words);
			_iVars->bufferLength = 0;
		}
	}
}

- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t *)_state;
		return (const unsigned char *)_iVars->state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1);
	_iVars->buffer.bytes[_iVars->bufferLength] = 0x80;
	of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0,
	    64 - _iVars->bufferLength - 1);

	if (_bufferLength >= 56) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 64);
	if (_iVars->bufferLength >= 56) {
		processBlock(_iVars->state, _iVars->buffer.words);
		of_explicit_memset(_iVars->buffer.bytes, 0, 64);
	}

	_iVars->buffer.words[14] =
	_buffer.words[14] = OF_BSWAP32_IF_LE((uint32_t)(_bits >> 32));
	_buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF));
	    OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits >> 32));
	_iVars->buffer.words[15] =
	    OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits & 0xFFFFFFFF));

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 8);
	processBlock(_iVars->state, _iVars->buffer.words);
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	byteSwapVectorIfLE(_iVars->state, 8);
	_calculated = true;

	return (const uint8_t *)_state;
	return (const unsigned char *)_iVars->state;
}

- (void)reset
{
	[self of_resetState];
	_bits = 0;
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	_iVars->bits = 0;
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	_iVars->bufferLength = 0;
	_calculated = false;
}

- (void)of_resetState
{
	OF_UNRECOGNIZED_SELECTOR
}
@end

Modified src/OFSHA256Hash.m from [ee7c2ddd35] to [5785cda739].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








38
39
23
24
25
26
27
28
29








30
31
32
33
34
35
36
37
38
39







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


+ (size_t)digestSize
{
	return 32;
}

- (void)of_resetState
{
	_state[0] = 0x6A09E667;
	_state[1] = 0xBB67AE85;
	_state[2] = 0x3C6EF372;
	_state[3] = 0xA54FF53A;
	_state[4] = 0x510E527F;
	_state[5] = 0x9B05688C;
	_state[6] = 0x1F83D9AB;
	_state[7] = 0x5BE0CD19;
	_iVars->state[0] = 0x6A09E667;
	_iVars->state[1] = 0xBB67AE85;
	_iVars->state[2] = 0x3C6EF372;
	_iVars->state[3] = 0xA54FF53A;
	_iVars->state[4] = 0x510E527F;
	_iVars->state[5] = 0x9B05688C;
	_iVars->state[6] = 0x1F83D9AB;
	_iVars->state[7] = 0x5BE0CD19;
}
@end

Modified src/OFSHA384Hash.m from [29b0925579] to [4945efba55].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








38
39
23
24
25
26
27
28
29








30
31
32
33
34
35
36
37
38
39







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


+ (size_t)digestSize
{
	return 48;
}

- (void)of_resetState
{
	_state[0] = 0xCBBB9D5DC1059ED8;
	_state[1] = 0x629A292A367CD507;
	_state[2] = 0x9159015A3070DD17;
	_state[3] = 0x152FECD8F70E5939;
	_state[4] = 0x67332667FFC00B31;
	_state[5] = 0x8EB44A8768581511;
	_state[6] = 0xDB0C2E0D64F98FA7;
	_state[7] = 0x47B5481DBEFA4FA4;
	_iVars->state[0] = 0xCBBB9D5DC1059ED8;
	_iVars->state[1] = 0x629A292A367CD507;
	_iVars->state[2] = 0x9159015A3070DD17;
	_iVars->state[3] = 0x152FECD8F70E5939;
	_iVars->state[4] = 0x67332667FFC00B31;
	_iVars->state[5] = 0x8EB44A8768581511;
	_iVars->state[6] = 0xDB0C2E0D64F98FA7;
	_iVars->state[7] = 0x47B5481DBEFA4FA4;
}
@end

Modified src/OFSHA384Or512Hash.h from [b64a6668e5] to [9c753764f8].

15
16
17
18
19
20
21


22
23
24
25
26
27
28


29
30
31
32
33
34
35








36
37
38
39
40
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
41
42
43
44
45







+
+







+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+





 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/*!
 * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h
 *
 * @brief A base class for SHA-384 and SHA-512.
 */
@interface OFSHA384Or512Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_sha384_or_512_hash_ivars {
	uint64_t _state[8];
	uint64_t _bits[2];
	union of_sha_384_or_512_hash_buffer {
		uint8_t bytes[128];
		uint64_t words[80];
	} _buffer;
	size_t _bufferLength;
		uint64_t state[8];
		uint64_t bits[2];
		union of_sha384_or_512_hash_buffer {
			uint8_t bytes[128];
			uint64_t words[80];
		} buffer;
		size_t bufferLength;
	} *_iVars;
	bool _calculated;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFSHA384Or512Hash.m from [12196f165c] to [9bae79c3a2].

17
18
19
20
21
22
23

24
25

26
27
28
29
30
31
32
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34







+


+








#include "config.h"

#include <stdlib.h>
#include <string.h>

#import "OFSHA384Or512Hash.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFOutOfRangeException.h"

@interface OFSHA384Or512Hash ()
- (void)of_resetState;
@end

static const uint64_t table[] = {
	0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F,
55
56
57
58
59
60
61
62

63
64
65

66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
57
58
59
60
61
62
63

64
65
66

67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+


-
+








-
+







	0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
	0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC,
	0x431D67C49C100D4C, 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A,
	0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
};

static OF_INLINE void
byteSwapVectorIfLE(uint64_t *vector, uint8_t length)
byteSwapVectorIfLE(uint64_t *vector, uint_fast8_t length)
{
#ifndef OF_BIG_ENDIAN
	for (uint8_t i = 0; i < length; i++)
	for (uint_fast8_t i = 0; i < length; i++)
		vector[i] = OF_BSWAP64(vector[i]);
#endif
}

static void
processBlock(uint64_t *state, uint64_t *buffer)
{
	uint64_t new[8];
	uint8_t i;
	uint_fast8_t i;

	new[0] = state[0];
	new[1] = state[1];
	new[2] = state[2];
	new[3] = state[3];
	new[4] = state[4];
	new[5] = state[5];
143
144
145
146
147
148
149




150
151
152
153
154
155
156
157
158
159
160
161
162





163
164
165
166

167
168
169
170
171
172
173

174
175
176

177
178

179
180
181
182
183
184
185
186
187

188
189
190
191
192



193
194
195



196
197
198

199
200
201
202

203
204


205
206
207
208
209
210
211



212
213
214
215
216
217
218
219

220
221
222



223
224
225
226



227
228
229
230


231
232
233
234



235
236
237

238
239
240
241
242
243
244
245



246
247
248
249
250
251
252
253
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183

184
185


186


187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204



205
206
207
208
209

210
211
212
213
214
215


216
217
218
219
220
221



222
223
224
225
226
227
228
229
230
231

232
233


234
235
236
237



238
239
240
241
242


243
244
245



246
247
248
249
250

251
252
253
254
255
256



257
258
259
260
261
262
263
264
265
266
267







+
+
+
+













+
+
+
+
+



-
+






-
+

-
-
+
-
-
+








-
+





+
+
+
-
-
-
+
+
+


-
+




+
-
-
+
+




-
-
-
+
+
+







-
+

-
-
+
+
+

-
-
-
+
+
+


-
-
+
+

-
-
-
+
+
+


-
+





-
-
-
+
+
+








}

- (instancetype)init
{
	self = [super init];

	@try {
		_iVarsData = [[OFSecureData alloc]
		    initWithCount: sizeof(*_iVars)];
		_iVars = [_iVarsData items];

		if ([self class] == [OFSHA384Or512Hash class]) {
			[self doesNotRecognizeSelector: _cmd];
			abort();
		}

		[self of_resetState];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)of_init
{
	return [super init];
}

- (void)dealloc
{
	[self reset];
	[_iVarsData release];

	[super dealloc];
}

- (id)copy
{
	OFSHA384Or512Hash *copy = [[[self class] alloc] init];
	OFSHA384Or512Hash *copy = [[[self class] alloc] of_init];

	memcpy(copy->_state, _state, sizeof(_state));
	memcpy(copy->_bits, _bits, sizeof(_bits));
	copy->_iVarsData = [_iVarsData copy];
	memcpy(&copy->_buffer, &_buffer, sizeof(_buffer));
	copy->_bufferLength = _bufferLength;
	copy->_iVars = [copy->_iVarsData items];
	copy->_calculated = _calculated;

	return copy;
}

- (void)updateWithBuffer: (const void *)buffer_
		  length: (size_t)length
{
	const uint8_t *buffer = buffer_;
	const unsigned char *buffer = buffer_;

	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithObject: self];

	if (length > SIZE_MAX / 8)
		@throw [OFOutOfRangeException exception];

	if (UINT64_MAX - _bits[0] < (length * 8))
		_bits[1]++;
	_bits[0] += (length * 8);
	if (UINT64_MAX - _iVars->bits[0] < (length * 8))
		_iVars->bits[1]++;
	_iVars->bits[0] += (length * 8);

	while (length > 0) {
		size_t min = 128 - _bufferLength;
		size_t min = 128 - _iVars->bufferLength;

		if (min > length)
			min = length;

		memcpy(_iVars->buffer.bytes + _iVars->bufferLength,
		memcpy(_buffer.bytes + _bufferLength, buffer, min);
		_bufferLength += min;
		    buffer, min);
		_iVars->bufferLength += min;

		buffer += min;
		length -= min;

		if (_bufferLength == 128) {
			processBlock(_state, _buffer.words);
			_bufferLength = 0;
		if (_iVars->bufferLength == 128) {
			processBlock(_iVars->state, _iVars->buffer.words);
			_iVars->bufferLength = 0;
		}
	}
}

- (const unsigned char *)digest
{
	if (_calculated)
		return (const uint8_t *)_state;
		return (const unsigned char *)_iVars->state;

	_buffer.bytes[_bufferLength] = 0x80;
	memset(_buffer.bytes + _bufferLength + 1, 0, 128 - _bufferLength - 1);
	_iVars->buffer.bytes[_iVars->bufferLength] = 0x80;
	of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0,
	    128 - _iVars->bufferLength - 1);

	if (_bufferLength >= 112) {
		processBlock(_state, _buffer.words);
		memset(_buffer.bytes, 0, 128);
	if (_iVars->bufferLength >= 112) {
		processBlock(_iVars->state, _iVars->buffer.words);
		of_explicit_memset(_iVars->buffer.bytes, 0, 128);
	}

	_buffer.words[14] = OF_BSWAP64_IF_LE(_bits[1]);
	_buffer.words[15] = OF_BSWAP64_IF_LE(_bits[0]);
	_iVars->buffer.words[14] = OF_BSWAP64_IF_LE(_iVars->bits[1]);
	_iVars->buffer.words[15] = OF_BSWAP64_IF_LE(_iVars->bits[0]);

	processBlock(_state, _buffer.words);
	memset(&_buffer, 0, sizeof(_buffer));
	byteSwapVectorIfLE(_state, 8);
	processBlock(_iVars->state, _iVars->buffer.words);
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	byteSwapVectorIfLE(_iVars->state, 8);
	_calculated = true;

	return (const uint8_t *)_state;
	return (const unsigned char *)_iVars->state;
}

- (void)reset
{
	[self of_resetState];
	memset(_bits, 0, sizeof(_bits));
	memset(&_buffer, 0, sizeof(_buffer));
	_bufferLength = 0;
	of_explicit_memset(_iVars->bits, 0, sizeof(_iVars->bits));
	of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer));
	_iVars->bufferLength = 0;
	_calculated = false;
}

- (void)of_resetState
{
	OF_UNRECOGNIZED_SELECTOR
}
@end

Modified src/OFSHA512Hash.m from [8e962810dd] to [81151a4040].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








38
39
23
24
25
26
27
28
29








30
31
32
33
34
35
36
37
38
39







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


+ (size_t)digestSize
{
	return 64;
}

- (void)of_resetState
{
	_state[0] = 0x6A09E667F3BCC908;
	_state[1] = 0xBB67AE8584CAA73B;
	_state[2] = 0x3C6EF372FE94F82B;
	_state[3] = 0xA54FF53A5F1D36F1;
	_state[4] = 0x510E527FADE682D1;
	_state[5] = 0x9B05688C2B3E6C1F;
	_state[6] = 0x1F83D9ABFB41BD6B;
	_state[7] = 0x5BE0CD19137E2179;
	_iVars->state[0] = 0x6A09E667F3BCC908;
	_iVars->state[1] = 0xBB67AE8584CAA73B;
	_iVars->state[2] = 0x3C6EF372FE94F82B;
	_iVars->state[3] = 0xA54FF53A5F1D36F1;
	_iVars->state[4] = 0x510E527FADE682D1;
	_iVars->state[5] = 0x9B05688C2B3E6C1F;
	_iVars->state[6] = 0x1F83D9ABFB41BD6B;
	_iVars->state[7] = 0x5BE0CD19137E2179;
}
@end

Modified src/OFSecureData.m from [9dff65470c] to [6ea795ac32].

79
80
81
82
83
84
85
86




87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123


124
125
126
127
128
129
130
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130







-
+
+
+
+








-
-

+














-
-




-
-




+
+








- (instancetype)initWithItemSize: (size_t)itemSize
			   count: (size_t)count
{
	self = [super init];

	@try {
		size_t size, pageSize;
		size_t size;
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		size_t pageSize;
#endif

		if OF_UNLIKELY (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		if OF_UNLIKELY (count > SIZE_MAX / itemSize)
			@throw [OFOutOfRangeException exception];

		size = itemSize * count;
		pageSize = [OFSystemInfo pageSize];

#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		pageSize = [OFSystemInfo pageSize];
		_mappingSize = OF_ROUND_UP_POW2(pageSize, size);

		if OF_UNLIKELY (_mappingSize < size)
			@throw [OFOutOfRangeException exception];

		if OF_UNLIKELY ((_items = mmap(NULL, _mappingSize,
		    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)) ==
		    MAP_FAILED)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: _mappingSize];

		if OF_UNLIKELY (mlock(_items, _mappingSize) != 0)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: _mappingSize];

		of_explicit_memset(_items, 0, _mappingSize);
#else
		if OF_UNLIKELY ((_items = malloc(size)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: size];

		of_explicit_memset(_items, 0, size);
#endif

		_itemSize = itemSize;
		_count = count;

		[self zero];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}