30                      :(NSString *)plaintext_password
   31{
   32  if (plaintext_password == nil)
   33    return nil;
   34 
   35  if (!(self = [super init]))
   36    return nil;
   37 
   38  _plaintext_password = [plaintext_password retain];
   39  const char *plaintext_password_data =
   40      [plaintext_password length] ? [plaintext_password UTF8String] : " ";
   41 
   42  if (!plaintext_password_data || !strlen(plaintext_password_data))
   43    [NSException raise:NSInternalInconsistencyException
   44                format:@"%s: plaintext password data is zero length!", __func__];
   45 
   46  uint8_t *derived_key = calloc(1, TSXEncryptorPBKDF2KeySize);
   47 
   48  if (CCKeyDerivationPBKDF != NULL)
   49  {
   50    int ret = CCKeyDerivationPBKDF(
   51        kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data) - 1,
   52        (const uint8_t *)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1,
   53        TSXEncryptorPBKDF2Rounds, derived_key, TSXEncryptorPBKDF2KeySize);
   54    
   55    
   56 
   57    if (ret)
   58    {
   59      NSLog(@"%s: CCKeyDerivationPBKDF ret == %d, indicating some sort of failure.", __func__,
   60            ret);
   61      free(derived_key);
   62      [self autorelease];
   63      return nil;
   64    }
   65  }
   66  else
   67  {
   68    
   69    unsigned long ret = PKCS5_PBKDF2_HMAC_SHA1(
   70        plaintext_password_data, (int)strlen(plaintext_password_data) - 1,
   71        (const unsigned char *)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen,
   72        TSXEncryptorPBKDF2Rounds, TSXEncryptorPBKDF2KeySize, derived_key);
   73    
   74    
   75 
   76    if (ret != 1)
   77    {
   78      NSLog(@"%s: PKCS5_PBKDF2_HMAC_SHA1 ret == %lu, indicating some sort of failure.",
   79            __func__, ret);
   80      free(derived_key);
   81      [self release];
   82      return nil;
   83    }
   84  }
   85 
   86  _encryption_key = [[NSData alloc] initWithBytesNoCopy:derived_key
   87                                                 length:TSXEncryptorPBKDF2KeySize
   88                                           freeWhenDone:YES];
   89  return self;
   90}