CK_RV init_token_data(CK_SLOT_ID slot_id) { CK_RV rc; memset((char *)nv_token_data, 0, sizeof(nv_token_data)); // the normal USER pin is not set when the token is initialized // memcpy(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE); memcpy(nv_token_data->so_pin_sha, default_so_pin_sha, SHA1_HASH_SIZE); memset(user_pin_md5, 0x0, MD5_HASH_SIZE); memcpy(so_pin_md5, default_so_pin_md5, MD5_HASH_SIZE); memcpy(nv_token_data->next_token_object_name, "00000000", 8); // generate the master key used for signing the Operation State information // ` memset(nv_token_data->token_info.label, ' ', sizeof(nv_token_data->token_info.label)); memcpy(nv_token_data->token_info.label, label, strlen((char *)label)); nv_token_data->tweak_vector.allow_weak_des = TRUE; nv_token_data->tweak_vector.check_des_parity = FALSE; nv_token_data->tweak_vector.allow_key_mods = TRUE; nv_token_data->tweak_vector.netscape_mods = TRUE; init_tokenInfo(); if (token_specific.t_init_token_data) { rc = token_specific.t_init_token_data(slot_id); if (rc != CKR_OK) return rc; } else { // // FIXME: erase the token object index file (and all token objects) // rc = generate_master_key(master_key); if (rc != CKR_OK) { TRACE_DEVEL("generate_master_key failed.\n"); return CKR_FUNCTION_FAILED; } rc = save_masterkey_so(); if (rc != CKR_OK) { TRACE_DEVEL("save_masterkey_so failed.\n"); return rc; } } rc = save_token_data(slot_id); return rc; }
CK_RV md2_hash( 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 || !out_data_len){ TRACE_ERROR("%s received bad argument(s)\n", __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = MD2_HASH_SIZE; return CKR_OK; } rc = md2_hash_update( tokdata, sess, ctx, in_data, in_data_len ); if (rc != CKR_OK){ TRACE_DEVEL("md2_hash_update failed.\n"); return CKR_FUNCTION_FAILED; } return md2_hash_final( tokdata, sess, FALSE, ctx, out_data, out_data_len ); }
CK_RV XProcUnLock(void) { if (spinxplfd != -1) flock(spinxplfd, LOCK_UN); else TRACE_DEVEL("No file descriptor to unlock with.\n"); return CKR_OK; }
RSA * openssl_gen_key() { RSA *rsa; int rc, counter = 0; char buf[32]; token_specific_rng((CK_BYTE *)buf, 32); RAND_seed(buf, 32); regen_rsa_key: rsa = RSA_generate_key(2048, 65537, NULL, NULL); if (rsa == NULL) { fprintf(stderr, "Error generating user's RSA key\n"); ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); return NULL; } rc = RSA_check_key(rsa); switch (rc) { case 0: /* rsa is not a valid RSA key */ RSA_free(rsa); counter++; if (counter == KEYGEN_RETRY) { TRACE_DEVEL("Tried %d times to generate a " "valid RSA key, failed.\n", KEYGEN_RETRY); return NULL; } goto regen_rsa_key; break; case 1: /* success case, rsa is a valid key */ break; case -1: /* fall through */ default: DEBUG_openssl_print_errors(); break; } return rsa; }
/* 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; }
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 );
int get_srk_info(struct srk_info *srk) { char *passwd_ptr = NULL; char *secret = NULL; int i; srk->mode = get_srk_mode(); if (srk->mode == -1) return -1; srk->secret = NULL; passwd_ptr = getenv("OCK_SRK_SECRET"); /* If nothing is set, then use original opencryptoki default of * secret is NULL and TSS_SECRET_MODE_PLAIN. */ if (passwd_ptr == NULL) { srk->len = 0; if (srk->mode == 0) { srk->mode = TSS_SECRET_MODE_PLAIN; return 0; } } else srk->len = strlen(passwd_ptr); /* A mode required at this point... */ if (srk->mode == 0) { TRACE_ERROR("SRK policy's secret mode is not set.\n"); return -1; } /* * getenv() returns a ptr to the actual string in our env, * so be sure to make a copy to avoid problems. */ if (srk->len != 0) { if ((secret = (char *)malloc(srk->len)) == NULL) { TRACE_ERROR("malloc of %d bytes failed.\n", srk->len); return -1; } memcpy(secret, passwd_ptr, srk->len); srk->secret = secret; } /* Secrets that are a hash, need to be converted from a * hex string to an array of bytes. */ if (srk->mode == TSS_SECRET_MODE_SHA1) { char *secret_h; int h_len = TPM_SHA1_160_HASH_LEN; if ((secret_h = (char *)malloc(h_len)) == NULL) { TRACE_ERROR("malloc of %d bytes failed.\n", h_len); goto error; } /* reuse passwd ptr since we dont need it anymore. */ passwd_ptr = secret; /* Assume hash is read in as string of hexidecimal digits. * 2 hex digits are required to represent a byte. * thus we need 2 * TPM_SHA1_160_HASH_LEN to * represent the hash. */ if (srk->len != (h_len * 2)) { free(secret_h); TRACE_DEVEL("Hashed secret is %d bytes, expected %d.\n", srk->len, h_len*2); goto error; } /* convert hexadecimal string into a byte array... */ for (i = 0; i < h_len; i++) { sscanf(passwd_ptr, "%2hhx", &secret_h[i]); passwd_ptr += 2; } srk->len = h_len; srk->secret = secret_h; free(secret); } return 0; error: if (secret) free(secret); return -1; }