]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
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); | |
df0e469f | 46 | |
bac41a7b A |
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); | |
df0e469f | 51 | |
bac41a7b A |
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 | } |