/* * Register a sign+hash algorithm derived from an algorithm supported * by the token + a software hash mechanism */ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, CK_MECHANISM_TYPE hash_mech, sc_pkcs11_mechanism_type_t *sign_type) { sc_pkcs11_mechanism_type_t *hash_type, *new_type; struct hash_signature_info *info; CK_MECHANISM_INFO mech_info = sign_type->mech_info; if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST))) return CKR_MECHANISM_INVALID; /* These hash-based mechs can only be used for sign/verify */ mech_info.flags &= (CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER); info = calloc(1, sizeof(*info)); info->mech = mech; info->sign_type = sign_type; info->hash_type = hash_type; info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_type, info); if (!new_type) return CKR_HOST_MEMORY; return sc_pkcs11_register_mechanism(p11card, new_type); }
CK_RV sc_pkcs11_md_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; if (!session || !session->slot || !(p11card = session->slot->card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_DIGEST); if (mt == NULL) return CKR_MECHANISM_INVALID; rv = session_start_operation(session, SC_PKCS11_OPERATION_DIGEST, mt, &operation); if (rv != CKR_OK) return rv; memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->md_init(operation); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST); return rv; }
/* * Initialize a verify context. When we get here, we know * the key object is capable of verifying _something_ */ CK_RV sc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; if (!session || !session->slot || !(p11card = session->slot->card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_VERIFY); if (mt == NULL) return CKR_MECHANISM_INVALID; /* See if compatible with key type */ if (mt->key_type != key_type) return CKR_KEY_TYPE_INCONSISTENT; rv = session_start_operation(session, SC_PKCS11_OPERATION_VERIFY, mt, &operation); if (rv != CKR_OK) return rv; memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->verif_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_VERIFY); return rv; }
/* * Initialize a signing context. When we get here, we know * the key object is capable of signing _something_ */ CK_RV sc_pkcs11_sign_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type) { struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; LOG_FUNC_CALLED(context); if (!session || !session->slot || !(p11card = session->slot->card)) LOG_FUNC_RETURN(context, CKR_ARGUMENTS_BAD); /* See if we support this mechanism type */ sc_log(context, "mechanism 0x%X, key-type 0x%X", pMechanism->mechanism, key_type); mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_SIGN); if (mt == NULL) LOG_FUNC_RETURN(context, CKR_MECHANISM_INVALID); /* See if compatible with key type */ if (mt->key_type != key_type) LOG_FUNC_RETURN(context, CKR_KEY_TYPE_INCONSISTENT); rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation); if (rv != CKR_OK) LOG_FUNC_RETURN(context, rv); memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->sign_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_SIGN); LOG_FUNC_RETURN(context, rv); }
CK_RV sc_pkcs11_get_mechanism_info(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mechanism, CK_MECHANISM_INFO_PTR pInfo) { sc_pkcs11_mechanism_type_t *mt; if (!(mt = sc_pkcs11_find_mechanism(p11card, mechanism, 0))) return CKR_MECHANISM_INVALID; memcpy(pInfo, &mt->mech_info, sizeof(*pInfo)); return CKR_OK; }