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

#include "config.h"

#include <stdlib.h>

#import "OFHMAC.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)
{

	size_t blocks, digestSize = [HMAC digestSize];


	unsigned char *extendedSalt;
	unsigned char buffer[digestSize];

	unsigned char digest[digestSize];

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


	@try {
		uint32_t i = OF_BSWAP32_IF_LE(1);

		[HMAC setKey: password
		      length: passwordLength];

		memcpy(extendedSalt, salt, saltLength);

		while (keyLength > 0) {
			size_t length;

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

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

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

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

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

			memcpy(key, buffer, 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);



		[HMAC zero];

		free(extendedSalt);
	}

}







>












>

>
>
|
|
>
|












<
<
|
>







|




|


|

|
|



|

|


|






|





|
|
|
|

>
>

|
<
|
>

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 *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];



	extendedSalt = [OFSecureData dataWithCount: saltLength + 4];
	extendedSaltItems = [extendedSalt items];

	@try {
		uint32_t i = OF_BSWAP32_IF_LE(1);

		[HMAC setKey: password
		      length: passwordLength];

		memcpy(extendedSaltItems, salt, saltLength);

		while (keyLength > 0) {
			size_t length;

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

			[HMAC reset];
			[HMAC updateWithBuffer: extendedSaltItems
					length: saltLength + 4];
			memcpy(bufferItems, [HMAC digest], digestSize);
			memcpy(digestItems, [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 k = 0; k < digestSize; k++)
					bufferItems[k] ^= digestItems[k];
			}

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

			memcpy(key, bufferItems, length);
			key += length;
			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];
	}


	objc_autoreleasePoolPop(pool);
}