#include "metaGlobal.h"
CK_RV
meta_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
{
CK_RV rv;
meta_session_t *session;
meta_object_t *key = NULL;
if (pMechanism == NULL || phKey == NULL)
return (CKR_ARGUMENTS_BAD);
rv = meta_handle2session(hSession, &session);
if (rv != CKR_OK)
return (rv);
rv = meta_object_alloc(session, &key);
if (rv != CKR_OK)
goto finish;
rv = meta_generate_keys(session, pMechanism, pTemplate, ulCount, key,
NULL, 0, NULL);
if (rv != CKR_OK)
goto finish;
meta_object_activate(key);
*phKey = (CK_OBJECT_HANDLE) key;
finish:
if (rv != CKR_OK) {
if (key)
(void) meta_object_dealloc(session, key, B_TRUE);
}
REFRELEASE(session);
return (rv);
}
CK_RV
meta_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
{
CK_RV rv;
meta_session_t *session;
meta_object_t *key1 = NULL, *key2 = NULL;
if (pMechanism == NULL || phPublicKey == NULL || phPrivateKey == NULL)
return (CKR_ARGUMENTS_BAD);
rv = meta_handle2session(hSession, &session);
if (rv != CKR_OK)
return (rv);
rv = meta_object_alloc(session, &key1);
if (rv != CKR_OK)
goto finish;
rv = meta_object_alloc(session, &key2);
if (rv != CKR_OK)
goto finish;
rv = meta_generate_keys(session, pMechanism,
pPublicKeyTemplate, ulPublicKeyAttributeCount, key1,
pPrivateKeyTemplate, ulPrivateKeyAttributeCount, key2);
if (rv != CKR_OK)
goto finish;
meta_object_activate(key1);
meta_object_activate(key2);
*phPublicKey = (CK_OBJECT_HANDLE) key1;
*phPrivateKey = (CK_OBJECT_HANDLE) key2;
finish:
if (rv != CKR_OK) {
if (key1)
(void) meta_object_dealloc(session, key1, B_TRUE);
if (key2)
(void) meta_object_dealloc(session, key2, B_TRUE);
}
REFRELEASE(session);
return (rv);
}
CK_RV
meta_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
{
CK_RV rv;
meta_session_t *session;
meta_object_t *wrappingKey, *inputKey;
if (pMechanism == NULL || pulWrappedKeyLen == NULL)
return (CKR_ARGUMENTS_BAD);
rv = meta_handle2session(hSession, &session);
if (rv != CKR_OK)
return (rv);
rv = meta_handle2object(hKey, &inputKey);
if (rv != CKR_OK) {
REFRELEASE(session);
return (rv);
}
rv = meta_handle2object(hWrappingKey, &wrappingKey);
if (rv != CKR_OK) {
OBJRELEASE(inputKey);
REFRELEASE(session);
return (rv);
}
rv = meta_wrap_key(session, pMechanism, wrappingKey,
inputKey, pWrappedKey, pulWrappedKeyLen);
OBJRELEASE(inputKey);
OBJRELEASE(wrappingKey);
REFRELEASE(session);
return (rv);
}
CK_RV
meta_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
{
CK_RV rv;
meta_session_t *session;
meta_object_t *unwrappingKey, *outputKey = NULL;
if (pMechanism == NULL || pWrappedKey == NULL || phKey == NULL)
return (CKR_ARGUMENTS_BAD);
rv = meta_handle2session(hSession, &session);
if (rv != CKR_OK)
return (rv);
rv = meta_handle2object(hUnwrappingKey, &unwrappingKey);
if (rv != CKR_OK) {
REFRELEASE(session);
return (rv);
}
rv = meta_object_alloc(session, &outputKey);
if (rv != CKR_OK)
goto finish;
(void) get_template_boolean(CKA_TOKEN, pTemplate, ulAttributeCount,
&(outputKey->isToken));
rv = meta_unwrap_key(session, pMechanism, unwrappingKey,
pWrappedKey, ulWrappedKeyLen,
pTemplate, ulAttributeCount, outputKey);
if (rv != CKR_OK)
goto finish;
meta_object_activate(outputKey);
*phKey = (CK_OBJECT_HANDLE) outputKey;
finish:
if (rv != CKR_OK) {
if (outputKey)
(void) meta_object_dealloc(session, outputKey, B_TRUE);
}
OBJRELEASE(unwrappingKey);
REFRELEASE(session);
return (rv);
}
CK_RV
meta_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
{
CK_RV rv;
CK_MECHANISM *pMech = pMechanism;
meta_session_t *session;
meta_object_t *basekey1 = NULL, *basekey2 = NULL;
meta_object_t *newKey1 = NULL, *newKey2 = NULL, *newKey3 = NULL,
*newKey4 = NULL;
boolean_t ssl_keys = B_FALSE;
boolean_t tlsprf = B_FALSE;
CK_MECHANISM metaMech;
CK_OBJECT_HANDLE *phBaseKey2 = NULL;
CK_X9_42_DH2_DERIVE_PARAMS x942_params, *x9_tmpptr;
CK_ECDH2_DERIVE_PARAMS ecdh_params, *ec_tmpptr;
CK_SSL3_KEY_MAT_OUT *ssl_key_mat;
CK_SSL3_KEY_MAT_PARAMS *keyparams;
if (pMech == NULL) {
return (CKR_ARGUMENTS_BAD);
}
switch (pMech->mechanism) {
case CKM_SSL3_KEY_AND_MAC_DERIVE:
case CKM_TLS_KEY_AND_MAC_DERIVE:
keyparams = (CK_SSL3_KEY_MAT_PARAMS*)pMech->pParameter;
if ((keyparams == NULL) || (pMech->ulParameterLen
!= sizeof (CK_SSL3_KEY_MAT_PARAMS)))
return (CKR_ARGUMENTS_BAD);
ssl_key_mat = keyparams->pReturnedKeyMaterial;
if (ssl_key_mat == NULL)
return (CKR_ARGUMENTS_BAD);
ssl_keys = B_TRUE;
break;
case CKM_TLS_PRF:
tlsprf = B_TRUE;
break;
default:
if (phKey == NULL)
return (CKR_ARGUMENTS_BAD);
};
rv = meta_handle2session(hSession, &session);
if (rv != CKR_OK)
return (rv);
rv = meta_handle2object(hBaseKey, &basekey1);
if (rv != CKR_OK)
goto finish;
switch (pMech->mechanism) {
case CKM_ECMQV_DERIVE:
if ((pMech->pParameter == NULL) || (pMech->ulParameterLen
!= sizeof (CK_ECDH2_DERIVE_PARAMS))) {
rv = CKR_ARGUMENTS_BAD;
goto finish;
}
ec_tmpptr = (CK_ECDH2_DERIVE_PARAMS *)pMech->pParameter;
ecdh_params = *ec_tmpptr;
metaMech = *pMech;
metaMech.pParameter = &ecdh_params;
pMech = &metaMech;
phBaseKey2 = &ecdh_params.hPrivateData;
break;
case CKM_X9_42_DH_HYBRID_DERIVE:
case CKM_X9_42_MQV_DERIVE:
if ((pMech->pParameter == NULL) || (pMech->ulParameterLen
!= sizeof (CK_X9_42_DH2_DERIVE_PARAMS))) {
rv = CKR_ARGUMENTS_BAD;
goto finish;
}
x9_tmpptr = (CK_X9_42_DH2_DERIVE_PARAMS *)pMech->pParameter;
x942_params = *x9_tmpptr;
metaMech = *pMech;
metaMech.pParameter = &x942_params;
pMech = &metaMech;
phBaseKey2 = &x942_params.hPrivateData;
break;
case CKM_CONCATENATE_BASE_AND_KEY:
if ((pMech->pParameter == NULL) || (pMech->ulParameterLen
!= sizeof (CK_OBJECT_HANDLE))) {
rv = CKR_ARGUMENTS_BAD;
goto finish;
}
metaMech = *pMech;
pMech = &metaMech;
phBaseKey2 = (CK_OBJECT_HANDLE *) &metaMech.pParameter;
break;
default:
break;
}
if (phBaseKey2) {
rv = meta_handle2object(*phBaseKey2, &basekey2);
if (rv != CKR_OK)
goto finish;
}
rv = meta_object_alloc(session, &newKey1);
if (rv != CKR_OK)
goto finish;
if (ssl_keys) {
rv = meta_object_alloc(session, &newKey2);
if (rv != CKR_OK)
goto finish;
rv = meta_object_alloc(session, &newKey3);
if (rv != CKR_OK)
goto finish;
rv = meta_object_alloc(session, &newKey4);
if (rv != CKR_OK)
goto finish;
}
rv = meta_derive_key(session, pMech, basekey1, basekey2, phBaseKey2,
pTemplate, ulAttributeCount, newKey1, newKey2, newKey3, newKey4);
if (rv != CKR_OK)
goto finish;
if (tlsprf) {
(void) meta_object_dealloc(session, newKey1, B_TRUE);
newKey1 = NULL;
} else {
meta_object_activate(newKey1);
if (ssl_keys) {
meta_object_activate(newKey2);
meta_object_activate(newKey3);
meta_object_activate(newKey4);
ssl_key_mat->hClientMacSecret
= (CK_OBJECT_HANDLE) newKey1;
ssl_key_mat->hServerMacSecret
= (CK_OBJECT_HANDLE) newKey2;
ssl_key_mat->hClientKey = (CK_OBJECT_HANDLE) newKey3;
ssl_key_mat->hServerKey = (CK_OBJECT_HANDLE) newKey4;
} else {
*phKey = (CK_OBJECT_HANDLE) newKey1;
}
}
finish:
if (rv != CKR_OK) {
if (newKey1)
(void) meta_object_dealloc(session, newKey1, B_TRUE);
if (newKey2)
(void) meta_object_dealloc(session, newKey2, B_TRUE);
if (newKey3)
(void) meta_object_dealloc(session, newKey3, B_TRUE);
if (newKey4)
(void) meta_object_dealloc(session, newKey4, B_TRUE);
}
if (basekey1)
OBJRELEASE(basekey1);
if (basekey2)
OBJRELEASE(basekey2);
REFRELEASE(session);
return (rv);
}