ObjFW  Diff

Differences From Artifact [7bd85babf9]:

To Artifact [ae8f98e1e6]:


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

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


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







+
-
+
-
-
-


-
+


-
+


-
+





-
-
+
+


-
-
+
+


-
+


-
-
+
+
+





-
-
+
+

-
+

-
+


-
+

-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+






-
-
+
+

-
-
-
+
+
+










-
+





#import "OFInvalidArgumentException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#import "pbkdf2.h"

void
void of_pbkdf2(OFHMAC *HMAC, size_t iterations,
of_pbkdf2(of_pbkdf2_parameters_t param)
    const unsigned char *salt, size_t saltLength,
    const char *password, size_t passwordLength,
    unsigned char *key, size_t keyLength, bool allowsSwappableMemory)
{
	void *pool = objc_autoreleasePoolPush();
	size_t blocks, digestSize = HMAC.digestSize;
	size_t blocks, digestSize = param.HMAC.digestSize;
	OFSecureData *buffer = [OFSecureData
		    dataWithCount: digestSize
	    allowsSwappableMemory: allowsSwappableMemory];
	    allowsSwappableMemory: param.allowsSwappableMemory];
	OFSecureData *digest = [OFSecureData
		    dataWithCount: digestSize
	    allowsSwappableMemory: allowsSwappableMemory];
	    allowsSwappableMemory: param.allowsSwappableMemory];
	unsigned char *bufferItems = buffer.mutableItems;
	unsigned char *digestItems = digest.mutableItems;
	OFSecureData *extendedSalt;
	unsigned char *extendedSaltItems;

	if (HMAC == nil || iterations == 0 || salt == NULL ||
	    password == NULL || key == NULL || keyLength == 0)
	if (param.HMAC == nil || param.iterations == 0 || param.salt == NULL ||
	    param.password == NULL || param.key == NULL || param.keyLength == 0)
		@throw [OFInvalidArgumentException exception];

	blocks = keyLength / digestSize;
	if (keyLength % digestSize != 0)
	blocks = param.keyLength / digestSize;
	if (param.keyLength % digestSize != 0)
		blocks++;

	if (saltLength > SIZE_MAX - 4 || blocks > UINT32_MAX)
	if (param.saltLength > SIZE_MAX - 4 || blocks > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	extendedSalt = [OFSecureData dataWithCount: saltLength + 4
			     allowsSwappableMemory: allowsSwappableMemory];
	extendedSalt = [OFSecureData
		    dataWithCount: param.saltLength + 4
	    allowsSwappableMemory: param.allowsSwappableMemory];
	extendedSaltItems = extendedSalt.mutableItems;

	@try {
		uint32_t i = OF_BSWAP32_IF_LE(1);

		[HMAC setKey: password
		      length: passwordLength];
		[param.HMAC setKey: param.password
			    length: param.passwordLength];

		memcpy(extendedSaltItems, salt, saltLength);
		memcpy(extendedSaltItems, param.salt, param.saltLength);

		while (keyLength > 0) {
		while (param.keyLength > 0) {
			size_t length;

			memcpy(extendedSaltItems + saltLength, &i, 4);
			memcpy(extendedSaltItems + param.saltLength, &i, 4);

			[HMAC reset];
			[HMAC updateWithBuffer: extendedSaltItems
					length: saltLength + 4];
			memcpy(bufferItems, HMAC.digest, digestSize);
			memcpy(digestItems, HMAC.digest, digestSize);
			[param.HMAC reset];
			[param.HMAC updateWithBuffer: extendedSaltItems
					      length: param.saltLength + 4];
			memcpy(bufferItems, param.HMAC.digest, digestSize);
			memcpy(digestItems, param.HMAC.digest, digestSize);

			for (size_t j = 1; j < iterations; j++) {
				[HMAC reset];
				[HMAC updateWithBuffer: digestItems
						length: digestSize];
				memcpy(digestItems, HMAC.digest, digestSize);
			for (size_t j = 1; j < param.iterations; j++) {
				[param.HMAC reset];
				[param.HMAC updateWithBuffer: digestItems
						      length: digestSize];
				memcpy(digestItems, param.HMAC.digest,
				    digestSize);

				for (size_t k = 0; k < digestSize; k++)
					bufferItems[k] ^= digestItems[k];
			}

			length = digestSize;
			if (length > keyLength)
				length = keyLength;
			if (length > param.keyLength)
				length = param.keyLength;

			memcpy(key, bufferItems, length);
			key += length;
			keyLength -= length;
			memcpy(param.key, bufferItems, length);
			param.key += length;
			param.keyLength -= length;

			i = OF_BSWAP32_IF_LE(OF_BSWAP32_IF_LE(i) + 1);
		}
	} @catch (id e) {
		[extendedSalt zero];
		[buffer zero];
		[digest zero];

		@throw e;
	} @finally {
		[HMAC zero];
		[param.HMAC zero];
	}

	objc_autoreleasePoolPop(pool);
}