X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/deriveKey.cpp diff --git a/libsecurity_apple_csp/lib/deriveKey.cpp b/libsecurity_apple_csp/lib/deriveKey.cpp deleted file mode 100644 index f329020c..00000000 --- a/libsecurity_apple_csp/lib/deriveKey.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS - * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT - * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the - * specific language governing rights and limitations under the License. - */ - - -/* - File: deriveKey.cpp - - Contains: CSSM_DeriveKey functions - - Copyright: (C) 2000 by Apple Computer, Inc., all rights reserved - - Written by: Doug Mitchell -*/ - -#include -#include -#include -#include -#include "AppleCSPSession.h" -#include "AppleCSPUtils.h" -#include "AppleCSPContext.h" -#include "cspdebugging.h" -#include -#include -#include "FEEAsymmetricContext.h" - -/* minimum legal values */ -#define PBKDF2_MIN_SALT 8 /* bytes */ -#define PBKDF2_MIN_ITER_CNT 1000 /* iteration count */ - -#define ALLOW_ZERO_PASSWORD 1 - -void AppleCSPSession::DeriveKey_PBKDF2( - const Context &context, - const CssmData &Param, - CSSM_DATA *keyData) -{ - /* validate algorithm-specific arguments */ - - /* Param must point to a CSSM_PKCS5_PBKDF2_PARAMS */ - if(Param.Length != sizeof(CSSM_PKCS5_PBKDF2_PARAMS)) { - errorLog0("DeriveKey_PBKDF2: Param wrong size\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER); - } - const CSSM_PKCS5_PBKDF2_PARAMS *pbkdf2Params = - reinterpret_cast(Param.Data); - if(pbkdf2Params == NULL) { - errorLog0("DeriveKey_PBKDF2: null Param.Data\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); - } - - /* Get passphrase from either baseKey or from CSSM_PKCS5_PBKDF2_PARAMS */ - CssmKey *passKey = context.get(CSSM_ATTRIBUTE_KEY); - CSSM_SIZE passphraseLen = 0; - uint8 *passphrase = NULL; - if(passKey != NULL) { - AppleCSPContext::symmetricKeyBits(context, *this, - CSSM_ALGID_SECURE_PASSPHRASE, CSSM_KEYUSE_DERIVE, - passphrase, passphraseLen); - } - else { - passphraseLen = pbkdf2Params->Passphrase.Length; - passphrase = pbkdf2Params->Passphrase.Data; - } - - #if !ALLOW_ZERO_PASSWORD - /* passphrase required */ - if(passphrase == NULL) { - errorLog0("DeriveKey_PBKDF2: null Passphrase\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); - } - if(passphraseLen == 0) { - /* FIXME - enforce minimum length? */ - errorLog0("DeriveKey_PBKDF2: zero length passphrase\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER); - } - #endif /* ALLOW_ZERO_PASSWORD */ - - if(pbkdf2Params->PseudoRandomFunction != - CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1) { - errorLog0("DeriveKey_PBKDF2: invalid PRF\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - - /* salt, from context, required */ - CssmData salt = context.get(CSSM_ATTRIBUTE_SALT, - CSSMERR_CSP_MISSING_ATTR_SALT); - if((salt.Data == NULL) || (salt.Length < PBKDF2_MIN_SALT)){ - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SALT); - } - - /* iteration count, from context, required */ - uint32 iterCount = context.getInt(CSSM_ATTRIBUTE_ITERATION_COUNT, - CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT); - if(iterCount < PBKDF2_MIN_ITER_CNT) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT); - } - - /* - * allocate a temp buffer, length - * = MAX (hLen, saltLen + 4) + 2 * hLen - * = MAX (kSHA1DigestSize, saltLen + 4) + 2 * kSHA1DigestSize - */ - size_t tempLen = salt.Length + 4; - if(tempLen < kSHA1DigestSize) { - tempLen = kSHA1DigestSize; - } - tempLen += (2 * kSHA1DigestSize); - CSSM_DATA tempData = {0, NULL}; - setUpData(tempData, tempLen, privAllocator); - - /* go */ - pbkdf2 (hmacsha1, - kSHA1DigestSize, - passphrase, (uint32)passphraseLen, - salt.Data, (uint32)salt.Length, - iterCount, - keyData->Data, (uint32)keyData->Length, - tempData.Data); - freeData(&tempData, privAllocator, false); -} - -/* - * PKCS5 v1.5 key derivation. Also used for traditional openssl key - * derivation, which is mighty similar to PKCS5 v1.5, with the addition - * of the ability to generate more than (keysize + ivsize) bytes. - */ -void AppleCSPSession::DeriveKey_PKCS5_V1_5( - const Context &context, - CSSM_ALGORITHMS algId, - const CssmData &Param, // IV optional, mallocd by app to indicate - // size - CSSM_DATA *keyData) // mallocd by caller to indicate size -{ - CSSM_DATA pwd = {0, NULL}; - - /* password from either Seed.Param or from base key */ - CssmCryptoData *cryptData = - context.get(CSSM_ATTRIBUTE_SEED); - if((cryptData != NULL) && (cryptData->Param.Length != 0)) { - pwd = cryptData->Param; - } - else { - /* Get secure passphrase from base key */ - CssmKey *passKey = context.get(CSSM_ATTRIBUTE_KEY); - if (passKey != NULL) { - AppleCSPContext::symmetricKeyBits(context, *this, - CSSM_ALGID_SECURE_PASSPHRASE, CSSM_KEYUSE_DERIVE, - pwd.Data, pwd.Length); - } - } - - if(pwd.Data == NULL) { - errorLog0("DeriveKey_PKCS5_V1_5: null Passphrase\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); - } - if(pwd.Length == 0) { - errorLog0("DeriveKey_PKCS5_V1_5: zero length passphrase\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_INPUT_POINTER); - } - - CSSM_ALGORITHMS hashAlg; - unsigned digestLen; - bool opensslAlg = false; - switch(algId) { - case CSSM_ALGID_PKCS5_PBKDF1_MD5: - hashAlg = CSSM_ALGID_MD5; - digestLen = kMD5DigestSize; - break; - case CSSM_ALGID_PKCS5_PBKDF1_MD2: - hashAlg = CSSM_ALGID_MD2; - digestLen = kMD2DigestSize; - break; - case CSSM_ALGID_PKCS5_PBKDF1_SHA1: - hashAlg = CSSM_ALGID_SHA1; - digestLen = kSHA1DigestSize; - break; - case CSSM_ALGID_PBE_OPENSSL_MD5: - hashAlg = CSSM_ALGID_MD5; - digestLen = kMD5DigestSize; - opensslAlg = true; - break; - default: - /* should not have been called */ - assert(0); - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - - /* IV optional */ - CSSM_DATA iv = Param; - - /* total requested length can't exceed digest size for struct PKCS5 v1.5*/ - if(!opensslAlg && ((keyData->Length + iv.Length) > digestLen)) { - errorLog0("DeriveKey_PKCS5_V1_5: requested length larger than digest\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); - } - - /* salt, from context, required */ - CssmData salt = context.get(CSSM_ATTRIBUTE_SALT, - CSSMERR_CSP_MISSING_ATTR_SALT); - if(salt.Data == NULL) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_SALT); - } - - /* iteration count, from context, required */ - uint32 iterCount = context.getInt(CSSM_ATTRIBUTE_ITERATION_COUNT, - CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT); - - /* - * Apply the underlying hash function Hash for c iterations to - * the concatenation of the password P and the salt S, then - * extract the first dkLen octets to produce a derived key DK: - * - * T1 = Hash (P || S) , - * T2 = Hash (T1) , - * ... - * Tc = Hash (Tc-1) , - * DK = Tc<0..dkLen-1> . - */ - DigestCtx ctx; - uint8 *keyDataP = keyData->Data; - size_t keyBytesToGo = keyData->Length; - uint8 *ivDataP = iv.Data; - size_t ivBytesToGo = iv.Length; - bool looping = false; // true for additional bytes for openssl - unsigned char digestOut[kMaxDigestSize]; - - for(;;) { - /* this loop guaranteed to only run once if !opensslAlg */ - DigestCtxInit(&ctx, hashAlg); - - if(looping) { - /* openssl addition: re-digest the digest here */ - DigestCtxUpdate(&ctx, digestOut, digestLen); - } - - /* digest password then salt */ - DigestCtxUpdate(&ctx, pwd.Data, (uint32)pwd.Length); - DigestCtxUpdate(&ctx, salt.Data, (uint32)salt.Length); - - DigestCtxFinal(&ctx, digestOut); - - /* now iterCount-1 more iterations */ - for(unsigned dex=1; dex bytesAvail) ? bytesAvail : keyBytesToGo; - memmove(keyDataP, digestOut, toMove); - uint8 *remainder = digestOut + toMove; - bytesAvail -= toMove; - keyDataP += toMove; - keyBytesToGo -= toMove; - - /* then optionally some to IV */ - if(ivBytesToGo && bytesAvail) { - toMove = (ivBytesToGo > bytesAvail) ? bytesAvail : ivBytesToGo; - memmove(ivDataP, remainder, toMove); - ivDataP += toMove; - ivBytesToGo -= toMove; - } - if((keyBytesToGo == 0) && (ivBytesToGo == 0)) { - /* guaranteed true for PKCS5 v1.5 */ - break; - } - - assert(opensslAlg == true); - looping = true; - } - DigestCtxFree(&ctx); -} - -/* - * Member function initially declared for CSPAbstractPluginSession; - * we're overriding the null version in CSPFullPluginSession. - * - * We'll generate any type of key (for now). - */ -void AppleCSPSession::DeriveKey( - CSSM_CC_HANDLE CCHandle, - const Context &context, - CssmData &Param, - uint32 KeyUsage, - uint32 KeyAttr, - const CssmData *KeyLabel, - const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, - CssmKey &DerivedKey) -{ - /* validate input args, common to all algorithms */ - switch(context.algorithm()) { - case CSSM_ALGID_PKCS5_PBKDF2: - case CSSM_ALGID_DH: - case CSSM_ALGID_PKCS12_PBE_ENCR: - case CSSM_ALGID_PKCS12_PBE_MAC: - case CSSM_ALGID_PKCS5_PBKDF1_MD5: - case CSSM_ALGID_PKCS5_PBKDF1_MD2: - case CSSM_ALGID_PKCS5_PBKDF1_SHA1: - case CSSM_ALGID_PBE_OPENSSL_MD5: - case CSSM_ALGID_OPENSSH1: - #if CRYPTKIT_CSP_ENABLE - case CSSM_ALGID_ECDH: - case CSSM_ALGID_ECDH_X963_KDF: - #endif - break; - /* maybe more here, later */ - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - DerivedKey.KeyData.Data = NULL; - DerivedKey.KeyData.Length = 0; - cspKeyStorage keyStorage = cspParseKeyAttr(CKT_Session, KeyAttr); - cspValidateKeyUsageBits(CKT_Session, KeyUsage); - - /* outgoing key type, required (though any algorithm is OK) */ - uint32 keyType = context.getInt(CSSM_ATTRIBUTE_KEY_TYPE, - CSSMERR_CSP_MISSING_ATTR_KEY_TYPE); - - /* outgoing key size, required - any nonzero value is OK */ - uint32 reqKeySize = context.getInt( - CSSM_ATTRIBUTE_KEY_LENGTH, - CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH); - - /* cook up a place to put the key data */ - uint32 keySizeInBytes = (reqKeySize + 7) / 8; - SymmetricBinaryKey *binKey = NULL; - CSSM_DATA_PTR keyData = NULL; - - switch(keyStorage) { - case CKS_None: - /* no way */ - CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK); - case CKS_Ref: - /* cook up a symmetric binary key */ - binKey = new SymmetricBinaryKey(reqKeySize); - keyData = &binKey->mKeyData; - break; - case CKS_Data: - /* key bytes --> caller's cssmKey */ - keyData = &DerivedKey.KeyData; - setUpData(*keyData, keySizeInBytes, - normAllocator); - break; - } - - /* break off to algorithm-specific code, whose job it is - * to fill in keyData->Data with keyData->Length bytes */ - switch(context.algorithm()) { - case CSSM_ALGID_PKCS5_PBKDF2: - DeriveKey_PBKDF2(context, - Param, - keyData); - break; - case CSSM_ALGID_DH: - DeriveKey_DH(context, - Param, - keyData, - *this); - break; - case CSSM_ALGID_PKCS12_PBE_ENCR: - case CSSM_ALGID_PKCS12_PBE_MAC: - DeriveKey_PKCS12(context, - *this, - Param, - keyData); - break; - case CSSM_ALGID_PKCS5_PBKDF1_MD5: - case CSSM_ALGID_PKCS5_PBKDF1_MD2: - case CSSM_ALGID_PKCS5_PBKDF1_SHA1: - case CSSM_ALGID_PBE_OPENSSL_MD5: - DeriveKey_PKCS5_V1_5(context, - context.algorithm(), - Param, - keyData); - break; - case CSSM_ALGID_OPENSSH1: - DeriveKey_OpenSSH1(context, - context.algorithm(), - Param, - keyData); - break; - #if CRYPTKIT_CSP_ENABLE - case CSSM_ALGID_ECDH: - case CSSM_ALGID_ECDH_X963_KDF: - CryptKit::DeriveKey_ECDH(context, - context.algorithm(), - Param, - keyData, - *this); - break; - #endif - /* maybe more here, later */ - default: - assert(0); - } - - /* set up outgoing header */ - KeyAttr &= ~KEY_ATTR_RETURN_MASK; - CSSM_KEYHEADER &hdr = DerivedKey.KeyHeader; - setKeyHeader(hdr, - plugin.myGuid(), - keyType, - CSSM_KEYCLASS_SESSION_KEY, - KeyAttr, - KeyUsage); - /* handle derived size < requested size, legal for Diffie-Hellman */ - hdr.LogicalKeySizeInBits = (uint32)(keyData->Length * 8); - - if(keyStorage == CKS_Ref) { - /* store and convert to ref key */ - addRefKey(*binKey, DerivedKey); - } - else { - /* Raw data */ - hdr.BlobType = CSSM_KEYBLOB_RAW; - hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING; - } -} -