CK_RV key_mgr_generate_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !handle){ TRACE_ERROR("%s received bad argument(s)\n", __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ TRACE_ERROR("%s received bad argument(s)\n", __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is CKO_SECRET_KEY, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)pTemplate[i].pValue; } switch (mech->mechanism) { case CKM_DES_KEY_GEN: if (subclass != 0 && subclass != CKK_DES){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES; break; case CKM_DES3_KEY_GEN: if (subclass != 0 && subclass != CKK_DES3){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES3; break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: if (subclass != 0 && subclass != CKK_CDMF){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_CDMF; break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: if (subclass != 0 && subclass != CKK_GENERIC_SECRET){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } if (mech->ulParameterLen != sizeof(CK_VERSION)){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } subclass = CKK_GENERIC_SECRET; break; case CKM_AES_KEY_GEN: if (subclass != 0 && subclass != CKK_AES){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCONSISTENT)); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_AES; break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, CKO_SECRET_KEY, subclass, &key_obj ); if (rc != CKR_OK){ TRACE_DEVEL("object_mgr_create_skel failed.\n"); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_DES_KEY_GEN: rc = ckm_des_key_gen( key_obj->template );
CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { CK_RV rc; CK_ULONG i, keyclass, keytype = 0 ; CK_ATTRIBUTE *new_attr ; OBJECT *temp_obj = NULL; OBJECT *secret_obj = NULL ; CK_BYTE secret_key_value[256] ; CK_ULONG count, secret_key_value_len = 256 ; CK_ATTRIBUTE *attr ; // Prelim checking of sess, mech, pTemplate, and ulCount was // done in the calling function (key_mgr_derive_key). // Perform DH checking of parameters // Check the existance of the public-value in mechanism if ((!mech->pParameter) || ((mech->ulParameterLen != 64) && (mech->ulParameterLen != 96) && (mech->ulParameterLen != 128) && (mech->ulParameterLen != 192) && (mech->ulParameterLen != 256))) { OCK_LOG_ERR(ERR_FUNCTION_FAILED); return CKR_FUNCTION_FAILED; } // Check valid object handle on base_key if (&base_key == NULL) { OCK_LOG_ERR(ERR_FUNCTION_FAILED); return CKR_FUNCTION_FAILED; } // Extract the object class and keytype from the supplied template. for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY) { OCK_LOG_ERR(ERR_TEMPLATE_INCONSISTENT); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) keytype = *(CK_ULONG *)pTemplate[i].pValue; } // Extract public-key from mechanism parameters. base-key contains the // private key, prime, and base. The return value will be in the handle. rc = ckm_dh_pkcs_derive( mech->pParameter, mech->ulParameterLen, base_key, secret_key_value, &secret_key_value_len ); if (rc != CKR_OK) { OCK_LOG_ERR(ERR_FUNCTION_FAILED); return CKR_FUNCTION_FAILED ; } // Build the attribute from the vales that were returned back rc = build_attribute( CKA_VALUE, secret_key_value, secret_key_value_len, &new_attr ); if (rc != CKR_OK) { OCK_LOG_ERR(ERR_FUNCTION_FAILED); return CKR_FUNCTION_FAILED ; } // Create the object that will be passed back as a handle. This will // contain the new (computed) value of the attribute. rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, keyclass, keytype, &temp_obj ); if (rc != CKR_OK){ OCK_LOG_ERR(ERR_OBJMGR_CREATE_SKEL); return rc; } // Update the template in the object with the new attribute template_update_attribute( temp_obj->template, new_attr );