]> git.saurik.com Git - apple/security.git/blob - AppleCSP/PBKDF2/pbkdf2.c
Security-176.tar.gz
[apple/security.git] / AppleCSP / PBKDF2 / pbkdf2.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: pbkdf2.c
21 Contains: Apple Data Security Services PKCS #5 PBKDF2 function definition.
22 Copyright: (C) 1999 by Apple Computer, Inc., all rights reserved
23 Written by: Michael Brouwer <mb@apple.com>
24 */
25 #include "pbkdf2.h"
26 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
27 #include <string.h>
28 /* Will write hLen bytes into dataPtr according to PKCS #5 2.0 spec.
29 See: http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-5.html for details.
30 tempBuffer is a pointer to at least MAX (hLen, saltLen + 4) + hLen bytes. */
31 static void
32 F (PRF prf, UInt32 hLen,
33 const void *passwordPtr, UInt32 passwordLen,
34 const void *saltPtr, UInt32 saltLen,
35 UInt32 iterationCount,
36 UInt32 blockNumber,
37 void *dataPtr,
38 void *tempBuffer)
39 {
40 UInt8 *inBlock, *outBlock, *resultBlockPtr;
41 UInt32 iteration;
42 outBlock = (UInt8*)tempBuffer;
43 inBlock = outBlock + hLen;
44 /* Set up inBlock to contain Salt || INT (blockNumber). */
45 memcpy (inBlock, saltPtr, saltLen);
46
47 inBlock[saltLen + 0] = (UInt8)(blockNumber >> 24);
48 inBlock[saltLen + 1] = (UInt8)(blockNumber >> 16);
49 inBlock[saltLen + 2] = (UInt8)(blockNumber >> 8);
50 inBlock[saltLen + 3] = (UInt8)(blockNumber);
51
52 /* Caculate U1 (result goes to outBlock) and copy it to resultBlockPtr. */
53 resultBlockPtr = (UInt8*)dataPtr;
54 prf (passwordPtr, passwordLen, inBlock, saltLen + 4, outBlock);
55 memcpy (resultBlockPtr, outBlock, hLen);
56 /* Calculate U2 though UiterationCount. */
57 for (iteration = 2; iteration <= iterationCount; iteration++)
58 {
59 UInt8 *tempBlock;
60 UInt32 byte;
61 /* Swap inBlock and outBlock pointers. */
62 tempBlock = inBlock;
63 inBlock = outBlock;
64 outBlock = tempBlock;
65 /* Now inBlock conatins Uiteration-1. Calclulate Uiteration into outBlock. */
66 prf (passwordPtr, passwordLen, inBlock, hLen, outBlock);
67 /* Xor data in dataPtr (U1 \xor U2 \xor ... \xor Uiteration-1) with
68 outBlock (Uiteration). */
69 for (byte = 0; byte < hLen; byte++)
70 resultBlockPtr[byte] ^= outBlock[byte];
71 }
72 }
73 void pbkdf2 (PRF prf, UInt32 hLen,
74 const void *passwordPtr, UInt32 passwordLen,
75 const void *saltPtr, UInt32 saltLen,
76 UInt32 iterationCount,
77 void *dkPtr, UInt32 dkLen,
78 void *tempBuffer)
79 {
80 UInt32 completeBlocks = dkLen / hLen;
81 UInt32 partialBlockSize = dkLen % hLen;
82 UInt32 blockNumber;
83 UInt8 *dataPtr = (UInt8*)dkPtr;
84 UInt8 *blkBuffer = (UInt8*)tempBuffer;
85 /* First cacluate all the complete hLen sized blocks required. */
86 for (blockNumber = 1; blockNumber <= completeBlocks; blockNumber++)
87 {
88 F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
89 iterationCount, blockNumber, dataPtr, blkBuffer + hLen);
90 dataPtr += hLen;
91 }
92 /* Finally if the requested output size was not an even multiple of hLen, calculate
93 the final block and copy the first partialBlockSize bytes of it to the output. */
94 if (partialBlockSize > 0)
95 {
96 F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
97 iterationCount, blockNumber, blkBuffer, blkBuffer + hLen);
98 memcpy (dataPtr, blkBuffer, partialBlockSize);
99 }
100 }