ObjFW  Check-in [a60d291359]

Overview
Comment:pbkdf2: 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: a60d291359ae5c03b0eec841f7f931f20f150cb979ae2c112b56bdbb75900a74
User & Date: js on 2018-04-08 22:56:38
Other Links: manifest | tags
Context
2018-04-08
23:39
runtime: Small fix for unregister_class() check-in: 8651ed04a0 user: js tags: trunk
22:56
pbkdf2: Make use of the new OFSecureData check-in: a60d291359 user: js tags: trunk
22:36
configure: Make sure -lpsplibc comes after -lgcc check-in: 0f6937eba9 user: js tags: trunk
Changes

Modified src/pbkdf2.m from [94e87aa2d2] to [6466d1abf3].

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







+












+

+
+
-
-
-
+
+
+
+












-
-
-
+
+







-
+




-
+


-
+

-
-
+
+



-
+

-
+


-
+






-
+





-
-
-
-
+
+
+
+

+
+

-
+
-
-
+
+

 */

#include "config.h"

#include <stdlib.h>

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

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

#import "pbkdf2.h"

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

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

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

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

	if ((extendedSalt = malloc(saltLength + 4)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: saltLength + 4];
	extendedSalt = [OFSecureData dataWithCount: saltLength + 4];
	extendedSaltItems = [extendedSalt items];

	@try {
		uint32_t i = OF_BSWAP32_IF_LE(1);

		[HMAC setKey: password
		      length: passwordLength];

		memcpy(extendedSalt, salt, saltLength);
		memcpy(extendedSaltItems, salt, saltLength);

		while (keyLength > 0) {
			size_t length;

			memcpy(extendedSalt + saltLength, &i, 4);
			memcpy(extendedSaltItems + saltLength, &i, 4);

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

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

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

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

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

			i = OF_BSWAP32_IF_LE(OF_BSWAP32_IF_LE(i) + 1);
		}
	} @finally {
		of_explicit_memset(extendedSalt, 0, saltLength + 4);
		of_explicit_memset(buffer, 0, digestSize);
		of_explicit_memset(digest, 0, digestSize);
	} @catch (id e) {
		[extendedSalt zero];
		[buffer zero];
		[digest zero];

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

	}
		free(extendedSalt);
	}

	objc_autoreleasePoolPop(pool);
}