Exemple #1
0
void
DeriveKey::operator () (CssmData *param, const KeySpec &spec,
						CssmKey &derivedKey)
{
	check(CSSM_DeriveKey(handle(), param, spec.usage, spec.attributes,
						 spec.label, &compositeRcc(), &derivedKey));
}
Exemple #2
0
Key
DeriveKey::operator () (CssmData *param, const KeySpec &spec)
{
	Key derivedKey;
	check(CSSM_DeriveKey(handle(), param, spec.usage, spec.attributes,
						 spec.label, &compositeRcc(),
						 derivedKey.makeNewKey(attachment())));
	derivedKey->activate();

	return derivedKey;
}
Exemple #3
0
/*
 * Derive a symmetric CSSM_KEY from the specified raw key material.
 */
CSSM_RETURN cdsaDeriveKey(
	CSSM_CSP_HANDLE		cspHandle,
	const void 			*rawKey,
	size_t				rawKeyLen,
	CSSM_ALGORITHMS		keyAlg,			// e.g., CSSM_ALGID_AES
	uint32				keySizeInBits,
	CSSM_KEY_PTR		key)
{
	CSSM_RETURN					crtn;
	CSSM_CC_HANDLE 				ccHand;
	CSSM_DATA					dummyLabel = {8, (uint8 *)"tempKey"};
	CSSM_DATA					saltData = {8, (uint8 *)"someSalt"};
	CSSM_PKCS5_PBKDF2_PARAMS 	pbeParams;
	CSSM_DATA					pbeData;
	CSSM_ACCESS_CREDENTIALS		creds;
	
	memset(key, 0, sizeof(CSSM_KEY));
	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
	crtn = CSSM_CSP_CreateDeriveKeyContext(cspHandle,
		CSSM_ALGID_PKCS5_PBKDF2,
		keyAlg,
		keySizeInBits,
		&creds,
		NULL,			// BaseKey
		1000,			// iterationCount, 1000 is the minimum
		&saltData,
		NULL,			// seed
		&ccHand);
	if(crtn) {
		return crtn;
	}
	
	/* this is the caller's raw key bits, typically ASCII (though it
	 * could be anything) */
	pbeParams.Passphrase.Data = (uint8 *)rawKey;
	pbeParams.Passphrase.Length = rawKeyLen;
	/* The only PRF supported by the CSP is HMACSHA1 */
	pbeParams.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
	pbeData.Data = (uint8 *)&pbeParams;
	pbeData.Length = sizeof(pbeParams);
	crtn = CSSM_DeriveKey(ccHand,
		&pbeData,
		CSSM_KEYUSE_ANY,
		CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE,
		&dummyLabel,
		NULL,			// cred and acl
		key);
	CSSM_DeleteContext(ccHand);		// ignore error here
	return crtn;
}
Exemple #4
0
/*
 * Perform Diffie-Hellman key exchange. 
 * Given "our" private key (in the form of a CSSM_KEY) and "their" public
 * key (in the form of a raw blob of bytes), cook up a symmetric key.
 */
CSSM_RETURN cdsaDhKeyExchange(
	CSSM_CSP_HANDLE	cspHandle,
	CSSM_KEY_PTR	myPrivateKey,			// from cdsaDhGenerateKeyPair
	const void		*theirPubKey,
	uint32			theirPubKeyLen,
	CSSM_KEY_PTR	derivedKey,				// RETURNED
	uint32			deriveKeySizeInBits,
	CSSM_ALGORITHMS	derivedKeyAlg)			// e.g., CSSM_ALGID_AES
{
	CSSM_RETURN 			crtn;
	CSSM_ACCESS_CREDENTIALS	creds;
	CSSM_CC_HANDLE			ccHandle;
	CSSM_DATA				labelData = {8, (uint8 *)"tempKey"};
	
	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
	memset(derivedKey, 0, sizeof(CSSM_KEY));
	
	crtn = CSSM_CSP_CreateDeriveKeyContext(cspHandle,
		CSSM_ALGID_DH,
		derivedKeyAlg,
		deriveKeySizeInBits,
		&creds,
		myPrivateKey,	// BaseKey
		0,				// IterationCount
		0,				// Salt
		0,				// Seed
		&ccHandle);
	if(crtn) {
		return crtn;
	}
	
	/* public key passed in as CSSM_DATA *Param */
	CSSM_DATA theirPubKeyData = { theirPubKeyLen, (uint8 *)theirPubKey };
	
	crtn = CSSM_DeriveKey(ccHandle,
		&theirPubKeyData,
		CSSM_KEYUSE_ANY, 
		CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE,
		&labelData,
		NULL,				// cread/acl
		derivedKey);
	CSSM_DeleteContext(ccHandle);
	return crtn;
}
/*
 * Derive symmetric key.
 * Note in the X CSP, we never return an IV. 
 */
CSSM_RETURN cuCspDeriveKey(CSSM_CSP_HANDLE cspHand,
		uint32				keyAlg,			// CSSM_ALGID_RC5, etc.
		const char 			*keyLabel,
		unsigned 			keyLabelLen,
		uint32 				keyUsage,		// CSSM_KEYUSE_ENCRYPT, etc.
		uint32 				keySizeInBits,
		CSSM_DATA_PTR		password,		// in PKCS-5 lingo
		CSSM_DATA_PTR		salt,			// ditto
		uint32				iterationCnt,	// ditto
		CSSM_KEY_PTR		key)
{
	CSSM_RETURN					crtn;
	CSSM_CC_HANDLE 				ccHand;
	uint32						keyAttr;
	CSSM_DATA					dummyLabel;
	CSSM_PKCS5_PBKDF2_PARAMS 	pbeParams;
	CSSM_DATA					pbeData;
	CSSM_ACCESS_CREDENTIALS		creds;
	
	memset(key, 0, sizeof(CSSM_KEY));
	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
	crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
		CSSM_ALGID_PKCS5_PBKDF2,
		keyAlg,
		keySizeInBits,
		&creds,
		NULL,			// BaseKey
		iterationCnt,
		salt,
		NULL,			// seed
		&ccHand);
	if(crtn) {
		cuPrintError("CSSM_CSP_CreateDeriveKeyContext", crtn);
		return crtn;
	}
	keyAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF | 
			  CSSM_KEYATTR_SENSITIVE;
	dummyLabel.Length = keyLabelLen;
	dummyLabel.Data = (uint8 *)keyLabel;
	
	/* passing in password is pretty strange....*/
	pbeParams.Passphrase = *password;
	pbeParams.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
	pbeData.Data = (uint8 *)&pbeParams;
	pbeData.Length = sizeof(pbeParams);
	crtn = CSSM_DeriveKey(ccHand,
		&pbeData,
		keyUsage,
		keyAttr,
		&dummyLabel,
		NULL,			// cred and acl
		key);
	if(crtn) {
		cuPrintError("CSSM_DeriveKey", crtn);
		return crtn;
	}
	crtn = CSSM_DeleteContext(ccHand);
	if(crtn) {
		cuPrintError("CSSM_DeleteContext", crtn);
	}
	return crtn;
}
CSSM_RETURN p12KeyGen(
	CSSM_CSP_HANDLE		cspHand,
	CSSM_KEY			&key,
	bool				isForEncr,	// true: en/decrypt   false: MAC
	CSSM_ALGORITHMS		keyAlg,
	CSSM_ALGORITHMS		pbeHashAlg,	// actually must be SHA1 for now
	uint32				keySizeInBits,
	uint32				iterCount,
	const CSSM_DATA		&salt,
	/* exactly one of the following two must be valid */
	const CSSM_DATA		*pwd,		// unicode external representation 
	const CSSM_KEY		*passKey,
	CSSM_DATA			&iv)		// referent is optional
{
	CSSM_RETURN					crtn;
	CSSM_CC_HANDLE 				ccHand;
	CSSM_DATA					dummyLabel;
	CSSM_ACCESS_CREDENTIALS		creds;
	
	memset(&key, 0, sizeof(CSSM_KEY));
	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));

	/* infer key derivation algorithm */
	CSSM_ALGORITHMS deriveAlg = CSSM_ALGID_NONE;
	if(pbeHashAlg != CSSM_ALGID_SHA1) {
		return CSSMERR_CSP_INVALID_ALGORITHM;
	}
	if(isForEncr) {
		/*
		 * FIXME - if this key is going to be used to wrap/unwrap a 
		 * shrouded key bag, its usage will change accordingly...
		 */
		deriveAlg = CSSM_ALGID_PKCS12_PBE_ENCR;
	}
	else {
		deriveAlg = CSSM_ALGID_PKCS12_PBE_MAC;
	}
	CSSM_CRYPTO_DATA seed;
	if(pwd) {
		seed.Param = *pwd;
	}
	else {
		seed.Param.Data = NULL;
		seed.Param.Length = 0;
	}
	seed.Callback = NULL;
	seed.CallerCtx = NULL;
	
	crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
		deriveAlg,
		keyAlg,
		keySizeInBits,
		&creds,
		passKey,		// BaseKey
		iterCount,
		&salt,
		&seed,			// seed
		&ccHand);
	if(crtn) {
		p12LogCssmError("CSSM_CSP_CreateDeriveKeyContext", crtn);
		return crtn;
	}
	
	dummyLabel.Length = strlen(KEY_LABEL);
	dummyLabel.Data = (uint8 *)KEY_LABEL;
	
	/* KEYUSE_ANY - this is just an ephemeral session key */
	crtn = CSSM_DeriveKey(ccHand,
		&iv,
		CSSM_KEYUSE_ANY,
		CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE,
		&dummyLabel,
		NULL,			// cred and acl
		&key);
	CSSM_DeleteContext(ccHand);
	if(crtn) {
		p12LogCssmError("CSSM_DeriveKey", crtn);
	}
	return crtn;
}
/* 
 * Common code to derive a wrap/unwrap key for OpenSSHv1.
 * Caller must CSSM_FreeKey when done.
 */
static CSSM_RETURN openSSHv1DeriveKey(
	CSSM_CSP_HANDLE		cspHand,
	const SecKeyImportExportParameters	*keyParams,		// required 
	impExpVerifyPhrase  verifyPhrase,					// for secure passphrase
	CSSM_KEY_PTR		symKey)							// RETURNED
{
	CSSM_KEY					*passKey = NULL;
	CFDataRef					cfPhrase = NULL;
	CSSM_RETURN					crtn;
	OSStatus					ortn;
	CSSM_DATA					dummyLabel;
	uint32						keyAttr;
	CSSM_CC_HANDLE 				ccHand = 0;
	CSSM_ACCESS_CREDENTIALS		creds;
	CSSM_CRYPTO_DATA			seed;
	CSSM_DATA					nullParam = {0, NULL};
	
	memset(symKey, 0, sizeof(CSSM_KEY));
	
	/* passphrase or passkey? */
	ortn = impExpPassphraseCommon(keyParams, cspHand, SPF_Data, verifyPhrase,
		(CFTypeRef *)&cfPhrase, &passKey);
	if(ortn) {
		return ortn;
	}
	/* subsequent errors to errOut: */

	memset(&seed, 0, sizeof(seed));
	if(cfPhrase != NULL) {
		/* TBD - caller-supplied empty passphrase means "export in the clear" */
		size_t len = CFDataGetLength(cfPhrase);
		seed.Param.Data = (uint8 *)malloc(len);
		seed.Param.Length = len;
		memmove(seed.Param.Data, CFDataGetBytePtr(cfPhrase), len);
		CFRelease(cfPhrase);
	}

	memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
	crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
		CSSM_ALGID_OPENSSH1,
		CSSM_ALGID_OPENSSH1,
		CC_MD5_DIGEST_LENGTH * 8,
		&creds,
		passKey,		// BaseKey
		0,				// iterationCount
		NULL,			// salt
		&seed,
		&ccHand);
	if(crtn) {
		SecSSHDbg("openSSHv1DeriveKey CSSM_CSP_CreateDeriveKeyContext failure");
		goto errOut;
	}
	
	/* not extractable even for the short time this key lives */
	keyAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_SENSITIVE;
	dummyLabel.Data = (uint8 *)"temp unwrap key";
	dummyLabel.Length = strlen((char *)dummyLabel.Data);
	
	crtn = CSSM_DeriveKey(ccHand,
		&nullParam,
		CSSM_KEYUSE_ANY,
		keyAttr,
		&dummyLabel,
		NULL,			// cred and acl
		symKey);
	if(crtn) {
		SecSSHDbg("openSSHv1DeriveKey CSSM_DeriveKey failure");
	}
errOut:
	if(ccHand != 0) {
		CSSM_DeleteContext(ccHand);
	}
	if(passKey != NULL) {
		CSSM_FreeKey(cspHand, NULL, passKey, CSSM_FALSE);
		free(passKey);
	}
	if(seed.Param.Data) {
		memset(seed.Param.Data, 0, seed.Param.Length);
		free(seed.Param.Data);
	}
	return crtn;
}