]>
git.saurik.com Git - apple/security.git/blob - sec/Security/pbkdf2.c
3a29fbfeeaad1bf6ce9c0953384186f577c4c932
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
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>
27 /* Will write hLen bytes into dataPtr according to PKCS #5 2.0 spec.
28 See: http://www.rsa.com/rsalabs/node.asp?id=2127 for details.
29 tempBuffer is a pointer to at least MAX (hLen, saltLen + 4) + hLen bytes. */
31 F (PRF prf
, size_t hLen
,
32 const void *passwordPtr
, size_t passwordLen
,
33 const void *saltPtr
, size_t saltLen
,
34 size_t iterationCount
,
39 uint8_t *inBlock
, *outBlock
, *resultBlockPtr
;
41 outBlock
= (uint8_t*)tempBuffer
;
42 inBlock
= outBlock
+ hLen
;
43 /* Set up inBlock to contain Salt || INT (blockNumber). */
44 memcpy (inBlock
, saltPtr
, saltLen
);
46 inBlock
[saltLen
+ 0] = (uint8_t)(blockNumber
>> 24);
47 inBlock
[saltLen
+ 1] = (uint8_t)(blockNumber
>> 16);
48 inBlock
[saltLen
+ 2] = (uint8_t)(blockNumber
>> 8);
49 inBlock
[saltLen
+ 3] = (uint8_t)(blockNumber
);
51 /* Caculate U1 (result goes to outBlock) and copy it to resultBlockPtr. */
52 resultBlockPtr
= (uint8_t*)dataPtr
;
53 prf (passwordPtr
, passwordLen
, inBlock
, saltLen
+ 4, outBlock
);
54 memcpy (resultBlockPtr
, outBlock
, hLen
);
55 /* Calculate U2 though UiterationCount. */
56 for (iteration
= 2; iteration
<= iterationCount
; iteration
++)
60 /* Swap inBlock and outBlock pointers. */
64 /* Now inBlock conatins Uiteration-1. Calculate Uiteration into outBlock. */
65 prf (passwordPtr
, passwordLen
, inBlock
, hLen
, outBlock
);
66 /* Xor data in dataPtr (U1 \xor U2 \xor ... \xor Uiteration-1) with
67 outBlock (Uiteration). */
68 for (byte
= 0; byte
< hLen
; byte
++)
69 resultBlockPtr
[byte
] ^= outBlock
[byte
];
72 void pbkdf2 (PRF prf
, size_t hLen
,
73 const void *passwordPtr
, size_t passwordLen
,
74 const void *saltPtr
, size_t saltLen
,
75 uint32_t iterationCount
,
76 void *dkPtr
, size_t dkLen
,
79 size_t completeBlocks
= dkLen
/ hLen
;
80 size_t partialBlockSize
= dkLen
% hLen
;
82 uint8_t *dataPtr
= (uint8_t*)dkPtr
;
83 uint8_t *blkBuffer
= (uint8_t*)tempBuffer
;
85 /* This check make sure that the following loops ends, in case where dk_len is 64 bits, and very large.
86 This will cause the derived key to be the maximum size supported by pbkdf2 (4GB * size of the hash)
87 rather than the actual requested size.*/
88 completeBlocks
=completeBlocks
& UINT32_MAX
;
90 /* First calculate all the complete hLen sized blocks required. */
91 for (blockNumber
= 1; blockNumber
<= completeBlocks
; blockNumber
++)
93 F (prf
, hLen
, passwordPtr
, passwordLen
, saltPtr
, saltLen
,
94 iterationCount
, blockNumber
, dataPtr
, blkBuffer
+ hLen
);
97 /* Finally if the requested output size was not an even multiple of hLen, calculate
98 the final block and copy the first partialBlockSize bytes of it to the output. */
99 if (partialBlockSize
> 0)
101 F (prf
, hLen
, passwordPtr
, passwordLen
, saltPtr
, saltLen
,
102 iterationCount
, blockNumber
, blkBuffer
, blkBuffer
+ hLen
);
103 memcpy (dataPtr
, blkBuffer
, partialBlockSize
);