Overview
Comment: | Implement PBKDF2 |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
49d1987eaf45a854c670e6fa4326b4e5 |
User & Date: | js on 2016-07-25 22:30:49 |
Other Links: | manifest | tags |
Context
2016-07-25
| ||
22:51 | Add missing files to Xcode project check-in: a5c7babba2 user: js tags: trunk | |
22:30 | Implement PBKDF2 check-in: 49d1987eaf user: js tags: trunk | |
2016-07-24
| ||
20:51 | OFHMAC: Allow resetting while keeping the key check-in: c55c5dff51 user: js tags: trunk | |
Changes
Modified src/Makefile from [40b697516a] to [6cddaa157f].
︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 | OFXMLProcessingInstructions.m \ OFZIPArchive.m \ OFZIPArchiveEntry.m \ base64.m \ crc32.m \ of_asprintf.m \ of_strptime.m \ unicode.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} SRCS_FILES = OFFile.m \ OFFileManager.m \ | > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | OFXMLProcessingInstructions.m \ OFZIPArchive.m \ OFZIPArchiveEntry.m \ base64.m \ crc32.m \ of_asprintf.m \ of_strptime.m \ pbkdf2.m \ unicode.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} SRCS_FILES = OFFile.m \ OFFileManager.m \ |
︙ | ︙ |
Modified src/OFHMAC.h from [fe33092934] to [72d5a8c0be].
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 | * @ref setKey:length:. * * @warning This invalidates any pointer previously returned by @ref digest. If * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref reset! */ - (void)reset; @end OF_ASSUME_NONNULL_END | > > > > > > > > | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | * @ref setKey:length:. * * @warning This invalidates any pointer previously returned by @ref digest. If * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref reset! */ - (void)reset; /*! * @brief This is like @ref reset, but also zeroes the hashed key and all state. * * @warning After calling this, you *must* set a new key before reusing the * HMAC! */ - (void)zero; @end OF_ASSUME_NONNULL_END |
Modified src/OFHMAC.m from [8de8a11875] to [25132018d7].
︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 | [_outerHash release]; [_innerHash release]; _outerHash = _innerHash = nil; _outerHash = [_outerHashCopy copy]; _innerHash = [_innerHashCopy copy]; _calculated = false; } @end | > > > > > > > > > > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | [_outerHash release]; [_innerHash release]; _outerHash = _innerHash = nil; _outerHash = [_outerHashCopy copy]; _innerHash = [_innerHashCopy copy]; _calculated = false; } - (void)zero { [_outerHash release]; [_innerHash release]; [_outerHashCopy release]; [_innerHashCopy release]; _outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil; _calculated = false; } @end |
Modified src/ObjFW.h from [99eb763c6d] to [9a3074fd4c].
︙ | ︙ | |||
200 201 202 203 204 205 206 | #import "crc32.h" #import "instance.h" #import "of_asprintf.h" #import "of_strptime.h" #ifdef OF_HAVE_SOCKETS # import "resolver.h" #endif | > | 200 201 202 203 204 205 206 207 | #import "crc32.h" #import "instance.h" #import "of_asprintf.h" #import "of_strptime.h" #ifdef OF_HAVE_SOCKETS # import "resolver.h" #endif #import "pbkdf2.h" |
Added src/pbkdf2.h version [8cf4fe8ea4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #import "macros.h" OF_ASSUME_NONNULL_BEGIN /*! @file */ @class OFHMAC; #ifdef __cplusplus extern "C" { #endif /*! * @brief Derive a key from a password and a salt. * * @note This will call @ref OFHMAC::reset on the @ref OFHMAC first, making it * possible to reuse the @ref OFHMAC, but also meaning all previous * results from the @ref OFHMAC get invalidated if they have not been * copied. * * @param HMAC The HMAC to use to derive a key * @param iterations The number of iterations to perform * @param salt The salt to derive a key with * @param saltLength The length of the salt * @param password The password to derive a key from * @param passwordLength The length of the password * @param key The buffer to write the key to * @param keyLength The desired length for the derived key (key needs to have * enough storage) */ extern 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); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/pbkdf2.m version [e70bcecc17].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #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 || saltLength == 0 || 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 { memset(extendedSalt, 0, saltLength + 4); memset(buffer, 0, digestSize); memset(digest, 0, digestSize); [HMAC zero]; free(extendedSalt); } } |
Modified tests/Makefile from [340c0b79d6] to [ce2c16d1ba].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | OFSetTests.m \ OFStreamTests.m \ OFStringTests.m \ OFURLTests.m \ OFXMLElementBuilderTests.m \ OFXMLNodeTests.m \ OFXMLParserTests.m \ RuntimeTests.m \ TestsAppDelegate.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} \ ${OFHTTPCLIENTTESTS_M} | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | OFSetTests.m \ OFStreamTests.m \ OFStringTests.m \ OFURLTests.m \ OFXMLElementBuilderTests.m \ OFXMLNodeTests.m \ OFXMLParserTests.m \ PBKDF2Tests.m \ RuntimeTests.m \ TestsAppDelegate.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} \ ${OFHTTPCLIENTTESTS_M} |
︙ | ︙ |
Added tests/PBKDF2Tests.m version [0612a8f8d4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFHMAC.h" #import "OFSHA1Hash.h" #import "OFString.h" #import "OFAutoreleasePool.h" #import "pbkdf2.h" #import "TestsAppDelegate.h" static OFString *module = @"PBKDF2"; @implementation TestsAppDelegate (PBKDF2Tests) - (void)PBKDF2Tests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFHMAC *HMAC = [OFHMAC HMACWithHashClass: [OFSHA1Hash class]]; unsigned char key[25]; /* Test vectors from RFC 6070 */ TEST(@"PBKDF2-SHA1, 1 iteration", R(of_pbkdf2(HMAC, 1, (unsigned char*)"salt", 4, "password", 8, key, 20)) && memcmp(key, "\x0C\x60\xC8\x0F\x96\x1F\x0E\x71\xF3\xA9\xB5\x24\xAF" "\x60\x12\x06\x2F\xE0\x37\xA6", 20) == 0) TEST(@"PBKDF2-SHA1, 2 iterations", R(of_pbkdf2(HMAC, 2, (unsigned char*)"salt", 4, "password", 8, key, 20)) && memcmp(key, "\xEA\x6C\x01\x4D\xC7\x2D\x6F\x8C\xCD\x1E\xD9\x2A\xCE" "\x1D\x41\xF0\xD8\xDE\x89\x57", 20) == 0) TEST(@"PBKDF2-SHA1, 4096 iterations", R(of_pbkdf2(HMAC, 4096, (unsigned char*)"salt", 4, "password", 8, key, 20)) && memcmp(key, "\x4B\x00\x79\x01\xB7\x65\x48\x9A\xBE\xAD\x49\xD9\x26" "\xF7\x21\xD0\x65\xA4\x29\xC1", 20) == 0) /* This test takes too long, even on a fast machine. */ #if 0 TEST(@"PBKDF2-SHA1, 16777216 iterations", R(of_pbkdf2(HMAC, 16777216, (unsigned char*)"salt", 4, "password", 8, key, 20)) && memcmp(key, "\xEE\xFE\x3D\x61\xCD\x4D\xA4\xE4\xE9\x94\x5B\x3D\x6B" "\xA2\x15\x8C\x26\x34\xE9\x84", 20) == 0) #endif TEST(@"PBKDF2-SHA1, 4096 iterations, key > 1 block", R(of_pbkdf2(HMAC, 4096, (unsigned char*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, "passwordPASSWORDpassword", 24, key, 25)) && memcmp(key, "\x3D\x2E\xEC\x4F\xE4\x1C\x84\x9B\x80\xC8\xD8\x36\x62" "\xC0\xE4\x4A\x8B\x29\x1A\x96\x4C\xF2\xF0\x70\x38", 25) == 0) TEST(@"PBKDF2-SHA1, 4096 iterations, key < 1 block", R(of_pbkdf2(HMAC, 4096, (unsigned char*)"sa\0lt", 5, "pass\0word", 9, key, 16)) && memcmp(key, "\x56\xFA\x6A\xA7\x55\x48\x09\x9D\xCC\x37\xD7\xF0\x34" "\x25\xE0\xC3", 16) == 0) [pool drain]; } @end |
Modified tests/TestsAppDelegate.h from [6bb325b98c] to [2f2d0cbc9c].
︙ | ︙ | |||
204 205 206 207 208 209 210 | - (void)XMLNodeTests; @end @interface TestsAppDelegate (OFXMLParserTests) <OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)XMLParserTests; @end | > > > > | 204 205 206 207 208 209 210 211 212 213 214 | - (void)XMLNodeTests; @end @interface TestsAppDelegate (OFXMLParserTests) <OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)XMLParserTests; @end @interface TestsAppDelegate (PBKDF2Tests) - (void)PBKDF2Tests; @end |
Modified tests/TestsAppDelegate.m from [60d1893094] to [fd9b7aac68].
︙ | ︙ | |||
381 382 383 384 385 386 387 388 389 390 391 392 393 394 | [self RIPEMD160HashTests]; [self SHA1HashTests]; [self SHA224HashTests]; [self SHA256HashTests]; [self SHA384HashTests]; [self SHA512HashTests]; [self HMACTests]; [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self TCPSocketTests]; [self UDPSocketTests]; [self kernelEventObserverTests]; #endif | > | 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | [self RIPEMD160HashTests]; [self SHA1HashTests]; [self SHA224HashTests]; [self SHA256HashTests]; [self SHA384HashTests]; [self SHA512HashTests]; [self HMACTests]; [self PBKDF2Tests]; [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self TCPSocketTests]; [self UDPSocketTests]; [self kernelEventObserverTests]; #endif |
︙ | ︙ |