aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/pkey_api.c
diff options
context:
space:
mode:
authorIngo Franzki <ifranzki@linux.ibm.com>2018-08-23 11:49:38 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-10 01:37:18 -0400
commitcb26b9ff7187ea79698f5e872d713f30affcc0a3 (patch)
tree8efa20448fa9ac8480880510a35d75795cc9186e /drivers/s390/crypto/pkey_api.c
parentaf504452d10ece7c6d68bc9f90f478ebecd7ce76 (diff)
s390/pkey: Introduce new API for random protected key verification
Introduce a new ioctl API and in-kernel API to verify if a random protected key is still valid. A protected key is invalid when its wrapping key verification pattern does not match the verification pattern of the LPAR. Each time an LPAR is activated, a new LPAR wrapping key is generated and the wrapping key verification pattern is updated. Both APIs are described in detail in the header files arch/s390/include/asm/pkey.h and arch/s390/include/uapi/asm/pkey.h. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/pkey_api.c')
-rw-r--r--drivers/s390/crypto/pkey_api.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index d0160a18081a..c592270b906a 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -20,6 +20,7 @@
20#include <asm/zcrypt.h> 20#include <asm/zcrypt.h>
21#include <asm/cpacf.h> 21#include <asm/cpacf.h>
22#include <asm/pkey.h> 22#include <asm/pkey.h>
23#include <crypto/aes.h>
23 24
24#include "zcrypt_api.h" 25#include "zcrypt_api.h"
25 26
@@ -1114,6 +1115,52 @@ int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey)
1114EXPORT_SYMBOL(pkey_genprotkey); 1115EXPORT_SYMBOL(pkey_genprotkey);
1115 1116
1116/* 1117/*
1118 * Verify if a protected key is still valid
1119 */
1120int pkey_verifyprotkey(const struct pkey_protkey *protkey)
1121{
1122 unsigned long fc;
1123 struct {
1124 u8 iv[AES_BLOCK_SIZE];
1125 u8 key[MAXPROTKEYSIZE];
1126 } param;
1127 u8 null_msg[AES_BLOCK_SIZE];
1128 u8 dest_buf[AES_BLOCK_SIZE];
1129 unsigned int k;
1130
1131 switch (protkey->type) {
1132 case PKEY_KEYTYPE_AES_128:
1133 fc = CPACF_KMC_PAES_128;
1134 break;
1135 case PKEY_KEYTYPE_AES_192:
1136 fc = CPACF_KMC_PAES_192;
1137 break;
1138 case PKEY_KEYTYPE_AES_256:
1139 fc = CPACF_KMC_PAES_256;
1140 break;
1141 default:
1142 DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__,
1143 protkey->type);
1144 return -EINVAL;
1145 }
1146
1147 memset(null_msg, 0, sizeof(null_msg));
1148
1149 memset(param.iv, 0, sizeof(param.iv));
1150 memcpy(param.key, protkey->protkey, sizeof(param.key));
1151
1152 k = cpacf_kmc(fc | CPACF_ENCRYPT, &param, null_msg, dest_buf,
1153 sizeof(null_msg));
1154 if (k != sizeof(null_msg)) {
1155 DEBUG_ERR("%s protected key is not valid\n", __func__);
1156 return -EKEYREJECTED;
1157 }
1158
1159 return 0;
1160}
1161EXPORT_SYMBOL(pkey_verifyprotkey);
1162
1163/*
1117 * File io functions 1164 * File io functions
1118 */ 1165 */
1119 1166
@@ -1243,6 +1290,16 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
1243 return -EFAULT; 1290 return -EFAULT;
1244 break; 1291 break;
1245 } 1292 }
1293 case PKEY_VERIFYPROTK: {
1294 struct pkey_verifyprotk __user *uvp = (void __user *) arg;
1295 struct pkey_verifyprotk kvp;
1296
1297 if (copy_from_user(&kvp, uvp, sizeof(kvp)))
1298 return -EFAULT;
1299 rc = pkey_verifyprotkey(&kvp.protkey);
1300 DEBUG_DBG("%s pkey_verifyprotkey()=%d\n", __func__, rc);
1301 break;
1302 }
1246 default: 1303 default:
1247 /* unknown/unsupported ioctl cmd */ 1304 /* unknown/unsupported ioctl cmd */
1248 return -ENOTTY; 1305 return -ENOTTY;
@@ -1504,7 +1561,7 @@ static struct miscdevice pkey_dev = {
1504 */ 1561 */
1505static int __init pkey_init(void) 1562static int __init pkey_init(void)
1506{ 1563{
1507 cpacf_mask_t pckmo_functions; 1564 cpacf_mask_t pckmo_functions, kmc_functions;
1508 1565
1509 /* check for pckmo instructions available */ 1566 /* check for pckmo instructions available */
1510 if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) 1567 if (!cpacf_query(CPACF_PCKMO, &pckmo_functions))
@@ -1514,6 +1571,14 @@ static int __init pkey_init(void)
1514 !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_256_KEY)) 1571 !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_256_KEY))
1515 return -EOPNOTSUPP; 1572 return -EOPNOTSUPP;
1516 1573
1574 /* check for kmc instructions available */
1575 if (!cpacf_query(CPACF_KMC, &kmc_functions))
1576 return -EOPNOTSUPP;
1577 if (!cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_128) ||
1578 !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_192) ||
1579 !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_256))
1580 return -EOPNOTSUPP;
1581
1517 pkey_debug_init(); 1582 pkey_debug_init();
1518 1583
1519 return misc_register(&pkey_dev); 1584 return misc_register(&pkey_dev);