CK_RV dp_dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } } else if (mode == MODE_KEYGEN) { found = template_attribute_find( tmpl, CKA_PRIME_BITS, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } } return dp_object_check_required_attributes( tmpl, mode ); }
CK_RV counter_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_HAS_RESET, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_RESET_ON_INIT, &attr ); if (!found) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } } return hwf_object_check_required_attributes( tmpl, mode ); }
CK_RV dp_dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_PRIME: if (mode == MODE_KEYGEN) { TRACE_ERROR("%s\n", ock_err(ERR_DOMAIN_PARAMS_INVALID)); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_PRIME_BITS: if (mode == MODE_CREATE) { TRACE_ERROR("%s\n", ock_err(ERR_DOMAIN_PARAMS_INVALID)); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_BASE: if (mode == MODE_KEYGEN) { TRACE_ERROR("%s\n", ock_err(ERR_DOMAIN_PARAMS_INVALID)); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; default: return dp_object_validate_attribute( tmpl, attr, mode ); } }
CK_RV digest_mgr_digest_update( STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ) { CK_RV rc; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED)); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: rc = sha_hash_update(tokdata, sess, ctx, data, data_len); break; #if !(NOMD2) case CKM_MD2: rc = md2_hash_update( tokdata, sess, ctx, data, data_len ); break; #endif case CKM_MD5: rc = md5_hash_update( tokdata, sess, ctx, data, data_len ); break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); rc = CKR_MECHANISM_INVALID; } if (rc != CKR_OK) { digest_mgr_cleanup(ctx); // "A call to C_DigestUpdate which results in an error // terminates the current digest operation." } return rc; }
CK_RV clock_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *value_attr; rc = hwf_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!value_attr) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; template_update_attribute( tmpl, value_attr ); return CKR_OK; }
CK_RV sw_des3_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_BYTE encrypt) { des_key_schedule des_key1; des_key_schedule des_key2; des_key_schedule des_key3; const_des_cblock key_SSL1, key_SSL2, key_SSL3; des_cblock ivec; // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8) { TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); return CKR_DATA_LEN_RANGE; } // The key as passed in is a 24 byte string containing 3 keys // pick it apart and create the key schedules memcpy(&key_SSL1, key_value, (size_t)8); memcpy(&key_SSL2, key_value+8, (size_t)8); memcpy(&key_SSL3, key_value+16, (size_t)8); des_set_key_unchecked(&key_SSL1, des_key1); des_set_key_unchecked(&key_SSL2, des_key2); des_set_key_unchecked(&key_SSL3, des_key3); memcpy(ivec, init_v, sizeof(ivec)); // Encrypt or decrypt the data if (encrypt) { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_ENCRYPT); *out_data_len = in_data_len; } else { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_DECRYPT); *out_data_len = in_data_len; } return CKR_OK; }
CK_RV digest_mgr_digest_key( STDLL_TokData_t *tokdata, SESSION * sess, DIGEST_CONTEXT * ctx, CK_OBJECT_HANDLE key_handle ) { CK_ATTRIBUTE * attr = NULL; OBJECT * key_obj = NULL; CK_OBJECT_CLASS class; CK_RV rc; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( tokdata, key_handle, &key_obj ); if (rc != CKR_OK){ TRACE_ERROR("%s\n", ock_err(ERR_KEY_HANDLE_INVALID)); rc = CKR_KEY_HANDLE_INVALID; goto out; } // only allow digesting of CKO_SECRET keys // rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr );
// hwf_object_validate_attribute() // CK_RV hwf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_HW_FEATURE_TYPE: if (mode == MODE_CREATE) return CKR_OK; else{ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY)); return CKR_ATTRIBUTE_READ_ONLY; } default: return template_validate_base_attribute( tmpl, attr, mode ); } TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID)); return CKR_ATTRIBUTE_TYPE_INVALID; }
CK_RV dp_dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *prime_attr; CK_ATTRIBUTE *base_attr; CK_ATTRIBUTE *primebits_attr; CK_ATTRIBUTE *type_attr; rc = dp_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); primebits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!prime_attr || !base_attr || !primebits_attr || !type_attr) { if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (primebits_attr) free( primebits_attr ); if (type_attr) free( type_attr ); TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; primebits_attr->type = CKA_PRIME_BITS; primebits_attr->ulValueLen = 0; primebits_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, primebits_attr ); template_update_attribute( tmpl, type_attr ); return CKR_OK; }
/* template_add_attributes() * * blindly add the given attributes to the template. do no sanity checking * at this point. sanity checking will occur later. */ CK_RV template_add_attributes(TEMPLATE *tmpl, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount) { CK_ATTRIBUTE *attr = NULL; CK_RV rc; unsigned int i; for (i = 0; i < ulCount; i++) { if (!is_attribute_defined(pTemplate[i].type)) { TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID)); return CKR_ATTRIBUTE_TYPE_INVALID; } attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + pTemplate[i].ulValueLen); if (!attr) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } attr->type = pTemplate[i].type; attr->ulValueLen = pTemplate[i].ulValueLen; if (attr->ulValueLen != 0) { attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); memcpy(attr->pValue, pTemplate[i].pValue, attr->ulValueLen); } else attr->pValue = NULL; rc = template_update_attribute(tmpl, attr); if (rc != CKR_OK) { free(attr); TRACE_DEVEL("template_update_attribute failed.\n"); return rc; } } return CKR_OK; }
// dp_object_validate_attribute() // CK_RV dp_object_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_KEY_TYPE: if (mode == MODE_CREATE) return CKR_OK; else{ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY)); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_LOCAL: if (mode == MODE_CREATE || mode == MODE_KEYGEN) { TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_TYPE_INVALID)); return CKR_ATTRIBUTE_TYPE_INVALID; } return CKR_OK; default: return template_validate_base_attribute( tmpl, attr, mode ); } }
CK_RV strip_pkcs_padding(CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len) { CK_BYTE pad_value; pad_value = ptr[total_len - 1]; if (pad_value > total_len) { TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_INVALID)); return CKR_ENCRYPTED_DATA_INVALID; } // thus, we have 'pad_value' bytes of 'pad_value' appended to the end // *data_len = total_len - pad_value; return CKR_OK; }
// dp_object_check_required_attributes() // // Check required common attributes for domain parameter objects // CK_RV dp_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_KEY_TYPE, &attr ); if (!found) { if (mode == MODE_CREATE){ TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } } return template_check_required_base_attributes( tmpl, mode ); }
CK_RV counter_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_VALUE: /* Fall Through */ case CKA_HAS_RESET: /* Fall Through */ case CKA_RESET_ON_INIT: TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY)); return CKR_ATTRIBUTE_READ_ONLY; default: return hwf_validate_attribute( tmpl, attr, mode ); } }
CK_RV counter_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *value_attr; CK_ATTRIBUTE *hasreset_attr; CK_ATTRIBUTE *resetoninit_attr; rc = hwf_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); hasreset_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL)); resetoninit_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL)); if (!value_attr || !hasreset_attr || !resetoninit_attr) { if (value_attr) free( value_attr ); if (hasreset_attr) free( hasreset_attr ); if (resetoninit_attr) free( resetoninit_attr ); TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; hasreset_attr->type = CKA_HAS_RESET; hasreset_attr->ulValueLen = sizeof(CK_BBOOL); hasreset_attr->pValue = (CK_BYTE *)hasreset_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)hasreset_attr->pValue = FALSE; /* Hmm... Not sure if we should be setting this here. */ resetoninit_attr->type = CKA_RESET_ON_INIT; resetoninit_attr->ulValueLen = sizeof(CK_BBOOL); resetoninit_attr->pValue = (CK_BYTE *)resetoninit_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)resetoninit_attr->pValue = FALSE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, hasreset_attr ); template_update_attribute( tmpl, resetoninit_attr ); return CKR_OK; }
// dp_object_set_default_attributes() // CK_RV dp_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * local_attr = NULL; local_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!local_attr) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = FALSE; template_update_attribute( tmpl, local_attr ); return CKR_OK; }
CK_RV build_attribute(CK_ATTRIBUTE_TYPE type, CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** attrib) { CK_ATTRIBUTE *attr = NULL; attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + data_len); if (!attr) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } attr->type = type; attr->ulValueLen = data_len; if (data_len > 0) { attr->pValue = (CK_BYTE *) attr + sizeof(CK_ATTRIBUTE); memcpy(attr->pValue, data, data_len); } else attr->pValue = NULL; *attrib = attr; return CKR_OK; }
CK_RV digest_mgr_init( STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ) { CK_RV rc = CKR_OK; CK_BYTE * ptr = NULL; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE)); return CKR_OPERATION_ACTIVE; } // is the mechanism supported? is the parameter present if required? // switch (mech->mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; rc = sha_init(tokdata, sess, ctx, mech); if (rc != CKR_OK) { digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("Failed to init sha context.\n"); return rc; } } break; case CKM_MD2: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD2_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD2_CONTEXT)); if (!ctx->context){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(MD2_CONTEXT) ); } break; case CKM_MD5: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD5_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD5_CONTEXT)); if (!ctx->context){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } ckm_md5_init( tokdata, (MD5_CONTEXT *)ctx->context ); } break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; }
CK_RV digest_mgr_digest( STDLL_TokData_t *tokdata, SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rc; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED)); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); rc = CKR_FUNCTION_FAILED; goto out; } if (ctx->multi == TRUE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE)); rc = CKR_OPERATION_ACTIVE; goto out; } switch (ctx->mech.mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: rc = sha_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; #if !(NOMD2 ) case CKM_MD2: rc = md2_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; #endif case CKM_MD5: rc = md5_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); rc = CKR_MECHANISM_INVALID; } out: if ( !((rc == CKR_BUFFER_TOO_SMALL) || (rc == CKR_OK && length_only == TRUE)) ) { // "A call to C_Digest always terminates the active digest operation unless it // returns CKR_BUFFER_TOO_SMALL or is a successful call (i.e., one which returns CKR_OK) // to determine the length of the buffer needed to hold the message digest." digest_mgr_cleanup(ctx); } return rc; }
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 );