]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/pbkdf2.c
   2  * Copyright (c) 2000-2001,2011,2013-2014 Apple 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,2011,2013-2014 Apple Inc. All Rights Reserved. 
  25 #include <ConditionalMacros.h> 
  27 /* Will write hLen bytes into dataPtr according to PKCS #5 2.0 spec. 
  28    See: http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-5.html for details.  
  29    tempBuffer is a pointer to at least MAX (hLen, saltLen + 4) + hLen bytes. */ 
  31 F (PRF prf
, uint32 hLen
, 
  32    const void *passwordPtr
, uint32 passwordLen
, 
  33    const void *saltPtr
, uint32 saltLen
, 
  34    uint32 iterationCount
, 
  39         uint8 
*inBlock
, *outBlock
, *resultBlockPtr
; 
  41         outBlock 
= (uint8
*)tempBuffer
; 
  42         inBlock 
= outBlock 
+ hLen
; 
  43         /* Set up inBlock to contain Salt || INT (blockNumber). */ 
  44         memcpy (inBlock
, saltPtr
, saltLen
); 
  46         inBlock
[saltLen 
+ 0] = (uint8
)(blockNumber 
>> 24); 
  47         inBlock
[saltLen 
+ 1] = (uint8
)(blockNumber 
>> 16); 
  48         inBlock
[saltLen 
+ 2] = (uint8
)(blockNumber 
>> 8); 
  49         inBlock
[saltLen 
+ 3] = (uint8
)(blockNumber
); 
  51         /* Caculate U1 (result goes to outBlock) and copy it to resultBlockPtr. */ 
  52         resultBlockPtr 
= (uint8
*)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.  Calclulate 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
, uint32 hLen
, 
  73                          const void *passwordPtr
, uint32 passwordLen
, 
  74                          const void *saltPtr
, uint32 saltLen
, 
  75                          uint32 iterationCount
, 
  76                          void *dkPtr
, uint32 dkLen
, 
  79         uint32 completeBlocks 
= dkLen 
/ hLen
; 
  80         uint32 partialBlockSize 
= dkLen 
% hLen
; 
  82         uint8 
*dataPtr 
= (uint8
*)dkPtr
; 
  83         uint8 
*blkBuffer 
= (uint8
*)tempBuffer
; 
  84         /* First calculate all the complete hLen sized blocks required. */ 
  85         for (blockNumber 
= 1; blockNumber 
<= completeBlocks
; blockNumber
++) 
  87                 F (prf
, hLen
, passwordPtr
, passwordLen
, saltPtr
, saltLen
, 
  88                    iterationCount
, blockNumber
, dataPtr
, blkBuffer 
+ hLen
); 
  91         /* Finally if the requested output size was not an even multiple of hLen, calculate 
  92            the final block and copy the first partialBlockSize bytes of it to the output. */ 
  93         if (partialBlockSize 
> 0) 
  95                 F (prf
, hLen
, passwordPtr
, passwordLen
, saltPtr
, saltLen
, 
  96                    iterationCount
, blockNumber
, blkBuffer
, blkBuffer 
+ hLen
); 
  97                 memcpy (dataPtr
, blkBuffer
, partialBlockSize
);