18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2001, 2019 48c2ecf20Sopenharmony_ci * Author(s): Robert Burroughs 58c2ecf20Sopenharmony_ci * Eric Rossman (edrossma@us.ibm.com) 68c2ecf20Sopenharmony_ci * Cornelia Huck <cornelia.huck@de.ibm.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 98c2ecf20Sopenharmony_ci * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 108c2ecf20Sopenharmony_ci * Ralph Wuerthner <rwuerthn@de.ibm.com> 118c2ecf20Sopenharmony_ci * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifndef _ZCRYPT_API_H_ 158c2ecf20Sopenharmony_ci#define _ZCRYPT_API_H_ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/atomic.h> 188c2ecf20Sopenharmony_ci#include <asm/debug.h> 198c2ecf20Sopenharmony_ci#include <asm/zcrypt.h> 208c2ecf20Sopenharmony_ci#include "ap_bus.h" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/** 238c2ecf20Sopenharmony_ci * Supported device types 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci#define ZCRYPT_CEX2C 5 268c2ecf20Sopenharmony_ci#define ZCRYPT_CEX2A 6 278c2ecf20Sopenharmony_ci#define ZCRYPT_CEX3C 7 288c2ecf20Sopenharmony_ci#define ZCRYPT_CEX3A 8 298c2ecf20Sopenharmony_ci#define ZCRYPT_CEX4 10 308c2ecf20Sopenharmony_ci#define ZCRYPT_CEX5 11 318c2ecf20Sopenharmony_ci#define ZCRYPT_CEX6 12 328c2ecf20Sopenharmony_ci#define ZCRYPT_CEX7 13 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/** 358c2ecf20Sopenharmony_ci * Large random numbers are pulled in 4096 byte chunks from the crypto cards 368c2ecf20Sopenharmony_ci * and stored in a page. Be careful when increasing this buffer due to size 378c2ecf20Sopenharmony_ci * limitations for AP requests. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci#define ZCRYPT_RNG_BUFFER_SIZE 4096 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* 428c2ecf20Sopenharmony_ci * Identifier for Crypto Request Performance Index 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_cienum crypto_ops { 458c2ecf20Sopenharmony_ci MEX_1K, 468c2ecf20Sopenharmony_ci MEX_2K, 478c2ecf20Sopenharmony_ci MEX_4K, 488c2ecf20Sopenharmony_ci CRT_1K, 498c2ecf20Sopenharmony_ci CRT_2K, 508c2ecf20Sopenharmony_ci CRT_4K, 518c2ecf20Sopenharmony_ci HWRNG, 528c2ecf20Sopenharmony_ci SECKEY, 538c2ecf20Sopenharmony_ci NUM_OPS 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistruct zcrypt_queue; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* struct to hold tracking information for a userspace request/response */ 598c2ecf20Sopenharmony_cistruct zcrypt_track { 608c2ecf20Sopenharmony_ci int again_counter; /* retry attempts counter */ 618c2ecf20Sopenharmony_ci int last_qid; /* last qid used */ 628c2ecf20Sopenharmony_ci int last_rc; /* last return code */ 638c2ecf20Sopenharmony_ci#ifdef CONFIG_ZCRYPT_DEBUG 648c2ecf20Sopenharmony_ci struct ap_fi fi; /* failure injection cmd */ 658c2ecf20Sopenharmony_ci#endif 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* defines related to message tracking */ 698c2ecf20Sopenharmony_ci#define TRACK_AGAIN_MAX 10 708c2ecf20Sopenharmony_ci#define TRACK_AGAIN_CARD_WEIGHT_PENALTY 1000 718c2ecf20Sopenharmony_ci#define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY 10000 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct zcrypt_ops { 748c2ecf20Sopenharmony_ci long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *, 758c2ecf20Sopenharmony_ci struct ap_message *); 768c2ecf20Sopenharmony_ci long (*rsa_modexpo_crt)(struct zcrypt_queue *, 778c2ecf20Sopenharmony_ci struct ica_rsa_modexpo_crt *, 788c2ecf20Sopenharmony_ci struct ap_message *); 798c2ecf20Sopenharmony_ci long (*send_cprb)(bool userspace, struct zcrypt_queue *, struct ica_xcRB *, 808c2ecf20Sopenharmony_ci struct ap_message *); 818c2ecf20Sopenharmony_ci long (*send_ep11_cprb)(bool userspace, struct zcrypt_queue *, struct ep11_urb *, 828c2ecf20Sopenharmony_ci struct ap_message *); 838c2ecf20Sopenharmony_ci long (*rng)(struct zcrypt_queue *, char *, struct ap_message *); 848c2ecf20Sopenharmony_ci struct list_head list; /* zcrypt ops list. */ 858c2ecf20Sopenharmony_ci struct module *owner; 868c2ecf20Sopenharmony_ci int variant; 878c2ecf20Sopenharmony_ci char name[128]; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistruct zcrypt_card { 918c2ecf20Sopenharmony_ci struct list_head list; /* Device list. */ 928c2ecf20Sopenharmony_ci struct list_head zqueues; /* List of zcrypt queues */ 938c2ecf20Sopenharmony_ci struct kref refcount; /* device refcounting */ 948c2ecf20Sopenharmony_ci struct ap_card *card; /* The "real" ap card device. */ 958c2ecf20Sopenharmony_ci int online; /* User online/offline */ 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci int user_space_type; /* User space device id. */ 988c2ecf20Sopenharmony_ci char *type_string; /* User space device name. */ 998c2ecf20Sopenharmony_ci int min_mod_size; /* Min number of bits. */ 1008c2ecf20Sopenharmony_ci int max_mod_size; /* Max number of bits. */ 1018c2ecf20Sopenharmony_ci int max_exp_bit_length; 1028c2ecf20Sopenharmony_ci const int *speed_rating; /* Speed idx of crypto ops. */ 1038c2ecf20Sopenharmony_ci atomic_t load; /* Utilization of the crypto device */ 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci int request_count; /* # current requests. */ 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistruct zcrypt_queue { 1098c2ecf20Sopenharmony_ci struct list_head list; /* Device list. */ 1108c2ecf20Sopenharmony_ci struct kref refcount; /* device refcounting */ 1118c2ecf20Sopenharmony_ci struct zcrypt_card *zcard; 1128c2ecf20Sopenharmony_ci struct zcrypt_ops *ops; /* Crypto operations. */ 1138c2ecf20Sopenharmony_ci struct ap_queue *queue; /* The "real" ap queue device. */ 1148c2ecf20Sopenharmony_ci int online; /* User online/offline */ 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci atomic_t load; /* Utilization of the crypto device */ 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci int request_count; /* # current requests. */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci struct ap_message reply; /* Per-device reply structure. */ 1218c2ecf20Sopenharmony_ci}; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* transport layer rescanning */ 1248c2ecf20Sopenharmony_ciextern atomic_t zcrypt_rescan_req; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ciextern spinlock_t zcrypt_list_lock; 1278c2ecf20Sopenharmony_ciextern int zcrypt_device_count; 1288c2ecf20Sopenharmony_ciextern struct list_head zcrypt_card_list; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#define for_each_zcrypt_card(_zc) \ 1318c2ecf20Sopenharmony_ci list_for_each_entry(_zc, &zcrypt_card_list, list) 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#define for_each_zcrypt_queue(_zq, _zc) \ 1348c2ecf20Sopenharmony_ci list_for_each_entry(_zq, &(_zc)->zqueues, list) 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistruct zcrypt_card *zcrypt_card_alloc(void); 1378c2ecf20Sopenharmony_civoid zcrypt_card_free(struct zcrypt_card *); 1388c2ecf20Sopenharmony_civoid zcrypt_card_get(struct zcrypt_card *); 1398c2ecf20Sopenharmony_ciint zcrypt_card_put(struct zcrypt_card *); 1408c2ecf20Sopenharmony_ciint zcrypt_card_register(struct zcrypt_card *); 1418c2ecf20Sopenharmony_civoid zcrypt_card_unregister(struct zcrypt_card *); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistruct zcrypt_queue *zcrypt_queue_alloc(size_t); 1448c2ecf20Sopenharmony_civoid zcrypt_queue_free(struct zcrypt_queue *); 1458c2ecf20Sopenharmony_civoid zcrypt_queue_get(struct zcrypt_queue *); 1468c2ecf20Sopenharmony_ciint zcrypt_queue_put(struct zcrypt_queue *); 1478c2ecf20Sopenharmony_ciint zcrypt_queue_register(struct zcrypt_queue *); 1488c2ecf20Sopenharmony_civoid zcrypt_queue_unregister(struct zcrypt_queue *); 1498c2ecf20Sopenharmony_civoid zcrypt_queue_force_online(struct zcrypt_queue *, int); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciint zcrypt_rng_device_add(void); 1528c2ecf20Sopenharmony_civoid zcrypt_rng_device_remove(void); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_civoid zcrypt_msgtype_register(struct zcrypt_ops *); 1558c2ecf20Sopenharmony_civoid zcrypt_msgtype_unregister(struct zcrypt_ops *); 1568c2ecf20Sopenharmony_cistruct zcrypt_ops *zcrypt_msgtype(unsigned char *, int); 1578c2ecf20Sopenharmony_ciint zcrypt_api_init(void); 1588c2ecf20Sopenharmony_civoid zcrypt_api_exit(void); 1598c2ecf20Sopenharmony_cilong zcrypt_send_cprb(struct ica_xcRB *xcRB); 1608c2ecf20Sopenharmony_cilong zcrypt_send_ep11_cprb(struct ep11_urb *urb); 1618c2ecf20Sopenharmony_civoid zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); 1628c2ecf20Sopenharmony_ciint zcrypt_device_status_ext(int card, int queue, 1638c2ecf20Sopenharmony_ci struct zcrypt_device_status_ext *devstatus); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic inline unsigned long z_copy_from_user(bool userspace, 1668c2ecf20Sopenharmony_ci void *to, 1678c2ecf20Sopenharmony_ci const void __user *from, 1688c2ecf20Sopenharmony_ci unsigned long n) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci if (likely(userspace)) 1718c2ecf20Sopenharmony_ci return copy_from_user(to, from, n); 1728c2ecf20Sopenharmony_ci memcpy(to, (void __force *) from, n); 1738c2ecf20Sopenharmony_ci return 0; 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic inline unsigned long z_copy_to_user(bool userspace, 1778c2ecf20Sopenharmony_ci void __user *to, 1788c2ecf20Sopenharmony_ci const void *from, 1798c2ecf20Sopenharmony_ci unsigned long n) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci if (likely(userspace)) 1828c2ecf20Sopenharmony_ci return copy_to_user(to, from, n); 1838c2ecf20Sopenharmony_ci memcpy((void __force *) to, from, n); 1848c2ecf20Sopenharmony_ci return 0; 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci#endif /* _ZCRYPT_API_H_ */ 188