ObjFW  Diff

Differences From Artifact [a56ad44126]:

To Artifact [8b7b7e738d]:


14
15
16
17
18
19
20

21
22
23
24
25
26
27
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28







+







 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFHMAC.h"
#import "OFSecureData.h"

#import "OFHashAlreadyCalculatedException.h"
#import "OFInvalidArgumentException.h"

@implementation OFHMAC
@synthesize hashClass = _hashClass;

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
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
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
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







+
+
-
+
+







+
-
-
+
+

-
-
+
+

-
-
-
+
+
+

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

-
-
+
+

-
-
-
-
+
+
+
+

-
-
+
+

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







}

- (void)setKey: (const void *)key
	length: (size_t)length
{
	void *pool = objc_autoreleasePoolPush();
	size_t blockSize = [_hashClass blockSize];
	OFSecureData *outerKeyPad = [OFSecureData dataWithCount: blockSize];
	OFSecureData *innerKeyPad = [OFSecureData dataWithCount: blockSize];
	uint8_t outerKeyPad[blockSize], innerKeyPad[blockSize];
	unsigned char *outerKeyPadItems = [outerKeyPad items];
	unsigned char *innerKeyPadItems = [innerKeyPad items];

	[_outerHash release];
	[_innerHash release];
	[_outerHashCopy release];
	[_innerHashCopy release];
	_outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil;

	@try {
	if (length > blockSize) {
		id <OFCryptoHash> hash = [_hashClass cryptoHash];
		if (length > blockSize) {
			id <OFCryptoHash> hash = [_hashClass cryptoHash];

		[hash updateWithBuffer: key
				length: length];
			[hash updateWithBuffer: key
					length: length];

		length = [_hashClass digestSize];
		if OF_UNLIKELY (length > blockSize)
			length = blockSize;
			length = [_hashClass digestSize];
			if OF_UNLIKELY (length > blockSize)
				length = blockSize;

		memcpy(outerKeyPad, [hash digest], length);
		memcpy(innerKeyPad, [hash digest], length);
	} else {
		memcpy(outerKeyPad, key, length);
		memcpy(innerKeyPad, key, length);
	}
			memcpy(outerKeyPadItems, [hash digest], length);
			memcpy(innerKeyPadItems, [hash digest], length);
		} else {
			memcpy(outerKeyPadItems, key, length);
			memcpy(innerKeyPadItems, key, length);
		}

	memset(outerKeyPad + length, 0, blockSize - length);
	memset(innerKeyPad + length, 0, blockSize - length);
		memset(outerKeyPadItems + length, 0, blockSize - length);
		memset(innerKeyPadItems + length, 0, blockSize - length);

	for (size_t i = 0; i < blockSize; i++) {
		outerKeyPad[i] ^= 0x5C;
		innerKeyPad[i] ^= 0x36;
	}
		for (size_t i = 0; i < blockSize; i++) {
			outerKeyPadItems[i] ^= 0x5C;
			innerKeyPadItems[i] ^= 0x36;
		}

	_outerHash = [[_hashClass cryptoHash] retain];
	_innerHash = [[_hashClass cryptoHash] retain];
		_outerHash = [[_hashClass cryptoHash] retain];
		_innerHash = [[_hashClass cryptoHash] retain];

	[_outerHash updateWithBuffer: outerKeyPad
			      length: blockSize];
	[_innerHash updateWithBuffer: innerKeyPad
			      length: blockSize];
		[_outerHash updateWithBuffer: outerKeyPadItems
				      length: blockSize];
		[_innerHash updateWithBuffer: innerKeyPadItems
				      length: blockSize];
	} @catch (id e) {
		[outerKeyPad zero];
		[innerKeyPad zero];
	}

	objc_autoreleasePoolPop(pool);

	_outerHashCopy = [_outerHash copy];
	_innerHashCopy = [_innerHash copy];

	_calculated = false;