Commit 5432114b authored by Ralph Wuerthner's avatar Ralph Wuerthner Committed by Martin Schwidefsky

[S390] zcrypt secure key cryptography extension.

Allow the user space to send extended cprb messages directly to the
PCIXCC / CEX2C cards. This allows the CCA library to construct special
crypto requests that use "secure" keys that are stored on the card.
Signed-off-by: default avatarRalph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent fe3a1be5
/*
* linux/drivers/s390/crypto/zcrypt_api.c
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......@@ -392,6 +392,41 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
return -ENODEV;
}
static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
{
struct zcrypt_device *zdev;
int rc;
spin_lock_bh(&zcrypt_device_lock);
list_for_each_entry(zdev, &zcrypt_device_list, list) {
if (!zdev->online || !zdev->ops->send_cprb ||
(xcRB->user_defined != AUTOSELECT &&
AP_QID_DEVICE(zdev->ap_dev->qid) != xcRB->user_defined)
)
continue;
zcrypt_device_get(zdev);
get_device(&zdev->ap_dev->device);
zdev->request_count++;
__zcrypt_decrease_preference(zdev);
spin_unlock_bh(&zcrypt_device_lock);
if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
rc = zdev->ops->send_cprb(zdev, xcRB);
module_put(zdev->ap_dev->drv->driver.owner);
}
else
rc = -EAGAIN;
spin_lock_bh(&zcrypt_device_lock);
zdev->request_count--;
__zcrypt_increase_preference(zdev);
put_device(&zdev->ap_dev->device);
zcrypt_device_put(zdev);
spin_unlock_bh(&zcrypt_device_lock);
return rc;
}
spin_unlock_bh(&zcrypt_device_lock);
return -ENODEV;
}
static void zcrypt_status_mask(char status[AP_DEVICES])
{
struct zcrypt_device *zdev;
......@@ -535,6 +570,18 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
return rc;
return put_user(crt.outputdatalength, &ucrt->outputdatalength);
}
case ZSECSENDCPRB: {
struct ica_xcRB __user *uxcRB = (void __user *) arg;
struct ica_xcRB xcRB;
if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB)))
return -EFAULT;
do {
rc = zcrypt_send_cprb(&xcRB);
} while (rc == -EAGAIN);
if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB)))
return -EFAULT;
return rc;
}
case Z90STAT_STATUS_MASK: {
char status[AP_DEVICES];
zcrypt_status_mask(status);
......@@ -683,6 +730,67 @@ static long trans_modexpo_crt32(struct file *filp, unsigned int cmd,
return rc;
}
struct compat_ica_xcRB {
unsigned short agent_ID;
unsigned int user_defined;
unsigned short request_ID;
unsigned int request_control_blk_length;
unsigned char padding1[16 - sizeof (compat_uptr_t)];
compat_uptr_t request_control_blk_addr;
unsigned int request_data_length;
char padding2[16 - sizeof (compat_uptr_t)];
compat_uptr_t request_data_address;
unsigned int reply_control_blk_length;
char padding3[16 - sizeof (compat_uptr_t)];
compat_uptr_t reply_control_blk_addr;
unsigned int reply_data_length;
char padding4[16 - sizeof (compat_uptr_t)];
compat_uptr_t reply_data_addr;
unsigned short priority_window;
unsigned int status;
} __attribute__((packed));
static long trans_xcRB32(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct compat_ica_xcRB __user *uxcRB32 = compat_ptr(arg);
struct compat_ica_xcRB xcRB32;
struct ica_xcRB xcRB64;
long rc;
if (copy_from_user(&xcRB32, uxcRB32, sizeof(xcRB32)))
return -EFAULT;
xcRB64.agent_ID = xcRB32.agent_ID;
xcRB64.user_defined = xcRB32.user_defined;
xcRB64.request_ID = xcRB32.request_ID;
xcRB64.request_control_blk_length =
xcRB32.request_control_blk_length;
xcRB64.request_control_blk_addr =
compat_ptr(xcRB32.request_control_blk_addr);
xcRB64.request_data_length =
xcRB32.request_data_length;
xcRB64.request_data_address =
compat_ptr(xcRB32.request_data_address);
xcRB64.reply_control_blk_length =
xcRB32.reply_control_blk_length;
xcRB64.reply_control_blk_addr =
compat_ptr(xcRB32.reply_control_blk_addr);
xcRB64.reply_data_length = xcRB32.reply_data_length;
xcRB64.reply_data_addr =
compat_ptr(xcRB32.reply_data_addr);
xcRB64.priority_window = xcRB32.priority_window;
xcRB64.status = xcRB32.status;
do {
rc = zcrypt_send_cprb(&xcRB64);
} while (rc == -EAGAIN);
xcRB32.reply_control_blk_length = xcRB64.reply_control_blk_length;
xcRB32.reply_data_length = xcRB64.reply_data_length;
xcRB32.status = xcRB64.status;
if (copy_to_user(uxcRB32, &xcRB32, sizeof(xcRB32)))
return -EFAULT;
return rc;
}
long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
......@@ -690,6 +798,8 @@ long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
return trans_modexpo32(filp, cmd, arg);
if (cmd == ICARSACRT)
return trans_modexpo_crt32(filp, cmd, arg);
if (cmd == ZSECSENDCPRB)
return trans_xcRB32(filp, cmd, arg);
return zcrypt_unlocked_ioctl(filp, cmd, arg);
}
#endif
......
/*
* linux/drivers/s390/crypto/zcrypt_api.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......@@ -106,6 +106,7 @@ struct zcrypt_ops {
long (*rsa_modexpo)(struct zcrypt_device *, struct ica_rsa_modexpo *);
long (*rsa_modexpo_crt)(struct zcrypt_device *,
struct ica_rsa_modexpo_crt *);
long (*send_cprb)(struct zcrypt_device *, struct ica_xcRB *);
};
struct zcrypt_device {
......
/*
* linux/drivers/s390/crypto/zcrypt_cca_key.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_cex2a.c
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_cex2a.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_error.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_mono.c
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_pcica.c
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_pcica.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_pcicc.c
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* linux/drivers/s390/crypto/zcrypt_pcicc.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
This diff is collapsed.
/*
* linux/drivers/s390/crypto/zcrypt_pcixcc.h
*
* zcrypt 2.0.0
* zcrypt 2.1.0
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......
/*
* include/asm-s390/zcrypt.h
*
* zcrypt 2.0.0 (user-visible header)
* zcrypt 2.1.0 (user-visible header)
*
* Copyright (C) 2001, 2006 IBM Corporation
* Author(s): Robert Burroughs
......@@ -79,6 +79,83 @@ struct ica_rsa_modexpo_crt {
char __user * u_mult_inv;
};
/**
* CPRBX
* Note that all shorts and ints are big-endian.
* All pointer fields are 16 bytes long, and mean nothing.
*
* A request CPRB is followed by a request_parameter_block.
*
* The request (or reply) parameter block is organized thus:
* function code
* VUD block
* key block
*/
struct ica_CPRBX {
unsigned short cprb_len; /* CPRB length 220 */
unsigned char cprb_ver_id; /* CPRB version id. 0x02 */
unsigned char pad_000[3]; /* Alignment pad bytes */
unsigned char func_id[2]; /* function id 0x5432 */
unsigned char cprb_flags[4]; /* Flags */
unsigned int req_parml; /* request parameter buffer len */
unsigned int req_datal; /* request data buffer */
unsigned int rpl_msgbl; /* reply message block length */
unsigned int rpld_parml; /* replied parameter block len */
unsigned int rpl_datal; /* reply data block len */
unsigned int rpld_datal; /* replied data block len */
unsigned int req_extbl; /* request extension block len */
unsigned char pad_001[4]; /* reserved */
unsigned int rpld_extbl; /* replied extension block len */
unsigned char padx000[16 - sizeof (char *)];
unsigned char * req_parmb; /* request parm block 'address' */
unsigned char padx001[16 - sizeof (char *)];
unsigned char * req_datab; /* request data block 'address' */
unsigned char padx002[16 - sizeof (char *)];
unsigned char * rpl_parmb; /* reply parm block 'address' */
unsigned char padx003[16 - sizeof (char *)];
unsigned char * rpl_datab; /* reply data block 'address' */
unsigned char padx004[16 - sizeof (char *)];
unsigned char * req_extb; /* request extension block 'addr'*/
unsigned char padx005[16 - sizeof (char *)];
unsigned char * rpl_extb; /* reply extension block 'addres'*/
unsigned short ccp_rtcode; /* server return code */
unsigned short ccp_rscode; /* server reason code */
unsigned int mac_data_len; /* Mac Data Length */
unsigned char logon_id[8]; /* Logon Identifier */
unsigned char mac_value[8]; /* Mac Value */
unsigned char mac_content_flgs;/* Mac content flag byte */
unsigned char pad_002; /* Alignment */
unsigned short domain; /* Domain */
unsigned char usage_domain[4];/* Usage domain */
unsigned char cntrl_domain[4];/* Control domain */
unsigned char S390enf_mask[4];/* S/390 enforcement mask */
unsigned char pad_004[36]; /* reserved */
};
/**
* xcRB
*/
struct ica_xcRB {
unsigned short agent_ID;
unsigned int user_defined;
unsigned short request_ID;
unsigned int request_control_blk_length;
unsigned char padding1[16 - sizeof (char *)];
char __user * request_control_blk_addr;
unsigned int request_data_length;
char padding2[16 - sizeof (char *)];
char __user * request_data_address;
unsigned int reply_control_blk_length;
char padding3[16 - sizeof (char *)];
char __user * reply_control_blk_addr;
unsigned int reply_data_length;
char padding4[16 - sizeof (char *)];
char __user * reply_data_addr;
unsigned short priority_window;
unsigned int status;
} __attribute__((packed));
#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
#define ZCRYPT_IOCTL_MAGIC 'z'
/**
......@@ -187,6 +264,7 @@ struct ica_rsa_modexpo_crt {
*/
#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
/* New status calls */
#define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment