]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 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" | |
427c49bc | 26 | #include <ConditionalMacros.h> |
b1ab9ed8 A |
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 calculate 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 | } |