162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright IBM Corp. 2001, 2019 462306a36Sopenharmony_ci * Author(s): Robert Burroughs 562306a36Sopenharmony_ci * Eric Rossman (edrossma@us.ibm.com) 662306a36Sopenharmony_ci * Cornelia Huck <cornelia.huck@de.ibm.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 962306a36Sopenharmony_ci * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 1062306a36Sopenharmony_ci * Ralph Wuerthner <rwuerthn@de.ibm.com> 1162306a36Sopenharmony_ci * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#ifndef _ZCRYPT_API_H_ 1562306a36Sopenharmony_ci#define _ZCRYPT_API_H_ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <linux/atomic.h> 1862306a36Sopenharmony_ci#include <asm/debug.h> 1962306a36Sopenharmony_ci#include <asm/zcrypt.h> 2062306a36Sopenharmony_ci#include "ap_bus.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/** 2362306a36Sopenharmony_ci * Supported device types 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci#define ZCRYPT_CEX2C 5 2662306a36Sopenharmony_ci#define ZCRYPT_CEX2A 6 2762306a36Sopenharmony_ci#define ZCRYPT_CEX3C 7 2862306a36Sopenharmony_ci#define ZCRYPT_CEX3A 8 2962306a36Sopenharmony_ci#define ZCRYPT_CEX4 10 3062306a36Sopenharmony_ci#define ZCRYPT_CEX5 11 3162306a36Sopenharmony_ci#define ZCRYPT_CEX6 12 3262306a36Sopenharmony_ci#define ZCRYPT_CEX7 13 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/** 3562306a36Sopenharmony_ci * Large random numbers are pulled in 4096 byte chunks from the crypto cards 3662306a36Sopenharmony_ci * and stored in a page. Be careful when increasing this buffer due to size 3762306a36Sopenharmony_ci * limitations for AP requests. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci#define ZCRYPT_RNG_BUFFER_SIZE 4096 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* 4262306a36Sopenharmony_ci * Identifier for Crypto Request Performance Index 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_cienum crypto_ops { 4562306a36Sopenharmony_ci MEX_1K, 4662306a36Sopenharmony_ci MEX_2K, 4762306a36Sopenharmony_ci MEX_4K, 4862306a36Sopenharmony_ci CRT_1K, 4962306a36Sopenharmony_ci CRT_2K, 5062306a36Sopenharmony_ci CRT_4K, 5162306a36Sopenharmony_ci HWRNG, 5262306a36Sopenharmony_ci SECKEY, 5362306a36Sopenharmony_ci NUM_OPS 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistruct zcrypt_queue; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* struct to hold tracking information for a userspace request/response */ 5962306a36Sopenharmony_cistruct zcrypt_track { 6062306a36Sopenharmony_ci int again_counter; /* retry attempts counter */ 6162306a36Sopenharmony_ci int last_qid; /* last qid used */ 6262306a36Sopenharmony_ci int last_rc; /* last return code */ 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* defines related to message tracking */ 6662306a36Sopenharmony_ci#define TRACK_AGAIN_MAX 10 6762306a36Sopenharmony_ci#define TRACK_AGAIN_CARD_WEIGHT_PENALTY 1000 6862306a36Sopenharmony_ci#define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY 10000 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistruct zcrypt_ops { 7162306a36Sopenharmony_ci long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *, 7262306a36Sopenharmony_ci struct ap_message *); 7362306a36Sopenharmony_ci long (*rsa_modexpo_crt)(struct zcrypt_queue *, 7462306a36Sopenharmony_ci struct ica_rsa_modexpo_crt *, 7562306a36Sopenharmony_ci struct ap_message *); 7662306a36Sopenharmony_ci long (*send_cprb)(bool userspace, struct zcrypt_queue *, struct ica_xcRB *, 7762306a36Sopenharmony_ci struct ap_message *); 7862306a36Sopenharmony_ci long (*send_ep11_cprb)(bool userspace, struct zcrypt_queue *, struct ep11_urb *, 7962306a36Sopenharmony_ci struct ap_message *); 8062306a36Sopenharmony_ci long (*rng)(struct zcrypt_queue *, char *, struct ap_message *); 8162306a36Sopenharmony_ci struct list_head list; /* zcrypt ops list. */ 8262306a36Sopenharmony_ci struct module *owner; 8362306a36Sopenharmony_ci int variant; 8462306a36Sopenharmony_ci char name[128]; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistruct zcrypt_card { 8862306a36Sopenharmony_ci struct list_head list; /* Device list. */ 8962306a36Sopenharmony_ci struct list_head zqueues; /* List of zcrypt queues */ 9062306a36Sopenharmony_ci struct kref refcount; /* device refcounting */ 9162306a36Sopenharmony_ci struct ap_card *card; /* The "real" ap card device. */ 9262306a36Sopenharmony_ci int online; /* User online/offline */ 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci int user_space_type; /* User space device id. */ 9562306a36Sopenharmony_ci char *type_string; /* User space device name. */ 9662306a36Sopenharmony_ci int min_mod_size; /* Min number of bits. */ 9762306a36Sopenharmony_ci int max_mod_size; /* Max number of bits. */ 9862306a36Sopenharmony_ci int max_exp_bit_length; 9962306a36Sopenharmony_ci const int *speed_rating; /* Speed idx of crypto ops. */ 10062306a36Sopenharmony_ci atomic_t load; /* Utilization of the crypto device */ 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci int request_count; /* # current requests. */ 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistruct zcrypt_queue { 10662306a36Sopenharmony_ci struct list_head list; /* Device list. */ 10762306a36Sopenharmony_ci struct kref refcount; /* device refcounting */ 10862306a36Sopenharmony_ci struct zcrypt_card *zcard; 10962306a36Sopenharmony_ci struct zcrypt_ops *ops; /* Crypto operations. */ 11062306a36Sopenharmony_ci struct ap_queue *queue; /* The "real" ap queue device. */ 11162306a36Sopenharmony_ci int online; /* User online/offline */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci atomic_t load; /* Utilization of the crypto device */ 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci int request_count; /* # current requests. */ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci struct ap_message reply; /* Per-device reply structure. */ 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* transport layer rescanning */ 12162306a36Sopenharmony_ciextern atomic_t zcrypt_rescan_req; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ciextern spinlock_t zcrypt_list_lock; 12462306a36Sopenharmony_ciextern struct list_head zcrypt_card_list; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#define for_each_zcrypt_card(_zc) \ 12762306a36Sopenharmony_ci list_for_each_entry(_zc, &zcrypt_card_list, list) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define for_each_zcrypt_queue(_zq, _zc) \ 13062306a36Sopenharmony_ci list_for_each_entry(_zq, &(_zc)->zqueues, list) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistruct zcrypt_card *zcrypt_card_alloc(void); 13362306a36Sopenharmony_civoid zcrypt_card_free(struct zcrypt_card *); 13462306a36Sopenharmony_civoid zcrypt_card_get(struct zcrypt_card *); 13562306a36Sopenharmony_ciint zcrypt_card_put(struct zcrypt_card *); 13662306a36Sopenharmony_ciint zcrypt_card_register(struct zcrypt_card *); 13762306a36Sopenharmony_civoid zcrypt_card_unregister(struct zcrypt_card *); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistruct zcrypt_queue *zcrypt_queue_alloc(size_t); 14062306a36Sopenharmony_civoid zcrypt_queue_free(struct zcrypt_queue *); 14162306a36Sopenharmony_civoid zcrypt_queue_get(struct zcrypt_queue *); 14262306a36Sopenharmony_ciint zcrypt_queue_put(struct zcrypt_queue *); 14362306a36Sopenharmony_ciint zcrypt_queue_register(struct zcrypt_queue *); 14462306a36Sopenharmony_civoid zcrypt_queue_unregister(struct zcrypt_queue *); 14562306a36Sopenharmony_cibool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ciint zcrypt_rng_device_add(void); 14862306a36Sopenharmony_civoid zcrypt_rng_device_remove(void); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_civoid zcrypt_msgtype_register(struct zcrypt_ops *); 15162306a36Sopenharmony_civoid zcrypt_msgtype_unregister(struct zcrypt_ops *); 15262306a36Sopenharmony_cistruct zcrypt_ops *zcrypt_msgtype(unsigned char *, int); 15362306a36Sopenharmony_ciint zcrypt_api_init(void); 15462306a36Sopenharmony_civoid zcrypt_api_exit(void); 15562306a36Sopenharmony_cilong zcrypt_send_cprb(struct ica_xcRB *xcRB); 15662306a36Sopenharmony_cilong zcrypt_send_ep11_cprb(struct ep11_urb *urb); 15762306a36Sopenharmony_civoid zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); 15862306a36Sopenharmony_ciint zcrypt_device_status_ext(int card, int queue, 15962306a36Sopenharmony_ci struct zcrypt_device_status_ext *devstatus); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ciint zcrypt_wait_api_operational(void); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic inline unsigned long z_copy_from_user(bool userspace, 16462306a36Sopenharmony_ci void *to, 16562306a36Sopenharmony_ci const void __user *from, 16662306a36Sopenharmony_ci unsigned long n) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci if (likely(userspace)) 16962306a36Sopenharmony_ci return copy_from_user(to, from, n); 17062306a36Sopenharmony_ci memcpy(to, (void __force *)from, n); 17162306a36Sopenharmony_ci return 0; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic inline unsigned long z_copy_to_user(bool userspace, 17562306a36Sopenharmony_ci void __user *to, 17662306a36Sopenharmony_ci const void *from, 17762306a36Sopenharmony_ci unsigned long n) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci if (likely(userspace)) 18062306a36Sopenharmony_ci return copy_to_user(to, from, n); 18162306a36Sopenharmony_ci memcpy((void __force *)to, from, n); 18262306a36Sopenharmony_ci return 0; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci#endif /* _ZCRYPT_API_H_ */ 186