aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/s390/include/asm/pkey.h8
-rw-r--r--arch/s390/include/uapi/asm/pkey.h9
-rw-r--r--drivers/s390/crypto/pkey_api.c67
3 files changed, 83 insertions, 1 deletions
diff --git a/arch/s390/include/asm/pkey.h b/arch/s390/include/asm/pkey.h
index c931818b9921..2833d6324979 100644
--- a/arch/s390/include/asm/pkey.h
+++ b/arch/s390/include/asm/pkey.h
@@ -117,4 +117,12 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
117 */ 117 */
118int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey); 118int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey);
119 119
120/*
121 * In-kernel API: Verify an (AES) protected key.
122 * @param protkey pointer to buffer containing the protected key to verify
123 * @return 0 on success, negative errno value on failure. In case the protected
124 * key is not valid -EKEYREJECTED is returned
125 */
126int pkey_verifyprotkey(const struct pkey_protkey *protkey);
127
120#endif /* _KAPI_PKEY_H */ 128#endif /* _KAPI_PKEY_H */
diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h
index 10a7bc7c5fa9..fef08dbd2e8d 100644
--- a/arch/s390/include/uapi/asm/pkey.h
+++ b/arch/s390/include/uapi/asm/pkey.h
@@ -139,4 +139,13 @@ struct pkey_genprotk {
139 139
140#define PKEY_GENPROTK _IOWR(PKEY_IOCTL_MAGIC, 0x08, struct pkey_genprotk) 140#define PKEY_GENPROTK _IOWR(PKEY_IOCTL_MAGIC, 0x08, struct pkey_genprotk)
141 141
142/*
143 * Verify an (AES) protected key.
144 */
145struct pkey_verifyprotk {
146 struct pkey_protkey protkey; /* in: the protected key to verify */
147};
148
149#define PKEY_VERIFYPROTK _IOW(PKEY_IOCTL_MAGIC, 0x09, struct pkey_verifyprotk)
150
142#endif /* _UAPI_PKEY_H */ 151#endif /* _UAPI_PKEY_H */
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);