pkey_pckmo.c (ea88e1710a9f19345c94c195f9cd7365e50343b0) | pkey_pckmo.c (8fcc231ce3bea12b78bb94b280cdc03cff342435) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * pkey pckmo specific code 4 * 5 * Copyright IBM Corp. 2024 6 */ 7 8#define KMSG_COMPONENT "pkey" 9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * pkey pckmo specific code 4 * 5 * Copyright IBM Corp. 2024 6 */ 7 8#define KMSG_COMPONENT "pkey" 9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10 |
11#include <linux/init.h> 12#include <linux/module.h> 13#include <linux/cpufeature.h> |
|
11#include <asm/cpacf.h> 12#include <crypto/aes.h> 13#include <linux/random.h> 14 15#include "zcrypt_api.h" 16#include "zcrypt_ccamisc.h" | 14#include <asm/cpacf.h> 15#include <crypto/aes.h> 16#include <linux/random.h> 17 18#include "zcrypt_api.h" 19#include "zcrypt_ccamisc.h" |
17 | |
18#include "pkey_base.h" 19 | 20#include "pkey_base.h" 21 |
20/* 21 * Prototypes 22 */ | 22MODULE_LICENSE("GPL"); 23MODULE_AUTHOR("IBM Corporation"); 24MODULE_DESCRIPTION("s390 protected key PCKMO handler"); |
23 | 25 |
24static bool is_pckmo_key(const u8 *key, u32 keylen); 25static int pckmo_key2protkey(const u8 *key, u32 keylen, 26 u8 *protkey, u32 *protkeylen, u32 *protkeytype); 27static int pckmo_gen_protkey(u32 keytype, 28 u8 *protkey, u32 *protkeylen, u32 *protkeytype); 29static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen, 30 u8 *protkey, u32 *protkeylen, u32 *protkeytype); 31static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen, 32 u32 protkeytype); 33 | |
34/* | 26/* |
35 * Wrapper functions 36 */ 37 38bool pkey_is_pckmo_key(const u8 *key, u32 keylen) 39{ 40 return is_pckmo_key(key, keylen); 41} 42 43int pkey_pckmo_key2protkey(u16 _card, u16 _dom, 44 const u8 *key, u32 keylen, 45 u8 *protkey, u32 *protkeylen, u32 *keyinfo) 46{ 47 return pckmo_key2protkey(key, keylen, 48 protkey, protkeylen, keyinfo); 49} 50 51int pkey_pckmo_gen_key(u16 _card, u16 _dom, 52 u32 keytype, u32 _keysubtype, 53 u32 _keybitsize, u32 _flags, 54 u8 *keybuf, u32 *keybuflen, u32 *keyinfo) 55{ 56 return pckmo_gen_protkey(keytype, 57 keybuf, keybuflen, keyinfo); 58} 59 60int pkey_pckmo_clr2key(u16 _card, u16 _dom, 61 u32 keytype, u32 _keysubtype, 62 u32 _keybitsize, u32 _flags, 63 const u8 *clrkey, u32 clrkeylen, 64 u8 *keybuf, u32 *keybuflen, u32 *keyinfo) 65{ 66 return pckmo_clr2protkey(keytype, clrkey, clrkeylen, 67 keybuf, keybuflen, keyinfo); 68} 69 70int pkey_pckmo_verifykey(const u8 *key, u32 keylen, 71 u16 *_card, u16 *_dom, 72 u32 *keytype, u32 *_keybitsize, u32 *_flags) 73{ 74 return pckmo_verify_protkey(key, keylen, *keytype); 75} 76 77/* | |
78 * Check key blob for known and supported here. 79 */ 80static bool is_pckmo_key(const u8 *key, u32 keylen) 81{ 82 struct keytoken_header *hdr = (struct keytoken_header *)key; 83 struct clearkeytoken *t = (struct clearkeytoken *)key; 84 85 if (keylen < sizeof(*hdr)) --- 21 unchanged lines hidden (view full) --- 107 default: 108 return false; 109 } 110 default: 111 return false; 112 } 113} 114 | 27 * Check key blob for known and supported here. 28 */ 29static bool is_pckmo_key(const u8 *key, u32 keylen) 30{ 31 struct keytoken_header *hdr = (struct keytoken_header *)key; 32 struct clearkeytoken *t = (struct clearkeytoken *)key; 33 34 if (keylen < sizeof(*hdr)) --- 21 unchanged lines hidden (view full) --- 56 default: 57 return false; 58 } 59 default: 60 return false; 61 } 62} 63 |
115static int pckmo_key2protkey(const u8 *key, u32 keylen, 116 u8 *protkey, u32 *protkeylen, u32 *protkeytype) | 64static bool is_pckmo_keytype(enum pkey_key_type keytype) |
117{ | 65{ |
118 struct keytoken_header *hdr = (struct keytoken_header *)key; 119 int rc = -EINVAL; 120 121 if (keylen < sizeof(*hdr)) 122 return -EINVAL; 123 if (hdr->type != TOKTYPE_NON_CCA) 124 return -EINVAL; 125 126 switch (hdr->version) { 127 case TOKVER_PROTECTED_KEY: { 128 struct protaeskeytoken *t; 129 130 if (keylen != sizeof(struct protaeskeytoken)) 131 goto out; 132 t = (struct protaeskeytoken *)key; 133 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype); 134 if (rc) 135 goto out; 136 memcpy(protkey, t->protkey, t->len); 137 *protkeylen = t->len; 138 *protkeytype = t->keytype; 139 break; 140 } 141 case TOKVER_CLEAR_KEY: { 142 struct clearkeytoken *t = (struct clearkeytoken *)key; 143 u32 keysize = 0; 144 145 if (keylen < sizeof(struct clearkeytoken) || 146 keylen != sizeof(*t) + t->len) 147 goto out; 148 switch (t->keytype) { 149 case PKEY_KEYTYPE_AES_128: 150 case PKEY_KEYTYPE_AES_192: 151 case PKEY_KEYTYPE_AES_256: 152 keysize = pkey_keytype_aes_to_size(t->keytype); 153 break; 154 case PKEY_KEYTYPE_ECC_P256: 155 keysize = 32; 156 break; 157 case PKEY_KEYTYPE_ECC_P384: 158 keysize = 48; 159 break; 160 case PKEY_KEYTYPE_ECC_P521: 161 keysize = 80; 162 break; 163 case PKEY_KEYTYPE_ECC_ED25519: 164 keysize = 32; 165 break; 166 case PKEY_KEYTYPE_ECC_ED448: 167 keysize = 64; 168 break; 169 default: 170 break; 171 } 172 if (!keysize) { 173 PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n", 174 __func__, t->keytype); 175 goto out; 176 } 177 if (t->len != keysize) { 178 PKEY_DBF_ERR("%s clear key token: invalid key len %u\n", 179 __func__, t->len); 180 goto out; 181 } 182 rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len, 183 protkey, protkeylen, protkeytype); 184 break; 185 } | 66 switch (keytype) { 67 case PKEY_TYPE_PROTKEY: 68 return true; |
186 default: | 69 default: |
187 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n", 188 __func__, hdr->version); 189 break; | 70 return false; |
190 } | 71 } |
191 192out: 193 pr_debug("rc=%d\n", rc); 194 return rc; | |
195} 196 197/* | 72} 73 74/* |
198 * Generate a random protected key. 199 * Currently only the generation of AES protected keys 200 * is supported. 201 */ 202static int pckmo_gen_protkey(u32 keytype, u8 *protkey, 203 u32 *protkeylen, u32 *protkeytype) 204{ 205 u8 clrkey[32]; 206 int keysize; 207 int rc; 208 209 keysize = pkey_keytype_aes_to_size(keytype); 210 if (!keysize) { 211 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", __func__, 212 keytype); 213 return -EINVAL; 214 } 215 216 /* generate a dummy random clear key */ 217 get_random_bytes(clrkey, keysize); 218 219 /* convert it to a dummy protected key */ 220 rc = pckmo_clr2protkey(keytype, clrkey, keysize, 221 protkey, protkeylen, protkeytype); 222 if (rc) 223 goto out; 224 225 /* replace the key part of the protected key with random bytes */ 226 get_random_bytes(protkey, keysize); 227 228out: 229 pr_debug("rc=%d\n", rc); 230 return rc; 231} 232 233/* | |
234 * Create a protected key from a clear key value via PCKMO instruction. 235 */ 236static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen, 237 u8 *protkey, u32 *protkeylen, u32 *protkeytype) 238{ 239 /* mask of available pckmo subfunctions */ 240 static cpacf_mask_t pckmo_functions; 241 --- 99 unchanged lines hidden (view full) --- 341 rc = 0; 342 343out: 344 pr_debug("rc=%d\n", rc); 345 return rc; 346} 347 348/* | 75 * Create a protected key from a clear key value via PCKMO instruction. 76 */ 77static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen, 78 u8 *protkey, u32 *protkeylen, u32 *protkeytype) 79{ 80 /* mask of available pckmo subfunctions */ 81 static cpacf_mask_t pckmo_functions; 82 --- 99 unchanged lines hidden (view full) --- 182 rc = 0; 183 184out: 185 pr_debug("rc=%d\n", rc); 186 return rc; 187} 188 189/* |
349 * Verify a protected key blob. | 190 * Verify a raw protected key blob. |
350 * Currently only AES protected keys are supported. 351 */ 352static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen, 353 u32 protkeytype) 354{ 355 struct { 356 u8 iv[AES_BLOCK_SIZE]; 357 u8 key[MAXPROTKEYSIZE]; --- 42 unchanged lines hidden (view full) --- 400 } 401 402 rc = 0; 403 404out: 405 pr_debug("rc=%d\n", rc); 406 return rc; 407} | 191 * Currently only AES protected keys are supported. 192 */ 193static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen, 194 u32 protkeytype) 195{ 196 struct { 197 u8 iv[AES_BLOCK_SIZE]; 198 u8 key[MAXPROTKEYSIZE]; --- 42 unchanged lines hidden (view full) --- 241 } 242 243 rc = 0; 244 245out: 246 pr_debug("rc=%d\n", rc); 247 return rc; 248} |
249 250static int pckmo_key2protkey(const u8 *key, u32 keylen, 251 u8 *protkey, u32 *protkeylen, u32 *protkeytype) 252{ 253 struct keytoken_header *hdr = (struct keytoken_header *)key; 254 int rc = -EINVAL; 255 256 if (keylen < sizeof(*hdr)) 257 return -EINVAL; 258 if (hdr->type != TOKTYPE_NON_CCA) 259 return -EINVAL; 260 261 switch (hdr->version) { 262 case TOKVER_PROTECTED_KEY: { 263 struct protaeskeytoken *t; 264 265 if (keylen != sizeof(struct protaeskeytoken)) 266 goto out; 267 t = (struct protaeskeytoken *)key; 268 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype); 269 if (rc) 270 goto out; 271 memcpy(protkey, t->protkey, t->len); 272 *protkeylen = t->len; 273 *protkeytype = t->keytype; 274 break; 275 } 276 case TOKVER_CLEAR_KEY: { 277 struct clearkeytoken *t = (struct clearkeytoken *)key; 278 u32 keysize = 0; 279 280 if (keylen < sizeof(struct clearkeytoken) || 281 keylen != sizeof(*t) + t->len) 282 goto out; 283 switch (t->keytype) { 284 case PKEY_KEYTYPE_AES_128: 285 case PKEY_KEYTYPE_AES_192: 286 case PKEY_KEYTYPE_AES_256: 287 keysize = pkey_keytype_aes_to_size(t->keytype); 288 break; 289 case PKEY_KEYTYPE_ECC_P256: 290 keysize = 32; 291 break; 292 case PKEY_KEYTYPE_ECC_P384: 293 keysize = 48; 294 break; 295 case PKEY_KEYTYPE_ECC_P521: 296 keysize = 80; 297 break; 298 case PKEY_KEYTYPE_ECC_ED25519: 299 keysize = 32; 300 break; 301 case PKEY_KEYTYPE_ECC_ED448: 302 keysize = 64; 303 break; 304 default: 305 break; 306 } 307 if (!keysize) { 308 PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n", 309 __func__, t->keytype); 310 goto out; 311 } 312 if (t->len != keysize) { 313 PKEY_DBF_ERR("%s clear key token: invalid key len %u\n", 314 __func__, t->len); 315 goto out; 316 } 317 rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len, 318 protkey, protkeylen, protkeytype); 319 break; 320 } 321 default: 322 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n", 323 __func__, hdr->version); 324 break; 325 } 326 327out: 328 pr_debug("rc=%d\n", rc); 329 return rc; 330} 331 332/* 333 * Generate a random protected key. 334 * Currently only the generation of AES protected keys 335 * is supported. 336 */ 337static int pckmo_gen_protkey(u32 keytype, u32 subtype, 338 u8 *protkey, u32 *protkeylen, u32 *protkeytype) 339{ 340 u8 clrkey[32]; 341 int keysize; 342 int rc; 343 344 keysize = pkey_keytype_aes_to_size(keytype); 345 if (!keysize) { 346 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", __func__, 347 keytype); 348 return -EINVAL; 349 } 350 if (subtype != PKEY_TYPE_PROTKEY) { 351 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 352 __func__, subtype); 353 return -EINVAL; 354 } 355 356 /* generate a dummy random clear key */ 357 get_random_bytes(clrkey, keysize); 358 359 /* convert it to a dummy protected key */ 360 rc = pckmo_clr2protkey(keytype, clrkey, keysize, 361 protkey, protkeylen, protkeytype); 362 if (rc) 363 goto out; 364 365 /* replace the key part of the protected key with random bytes */ 366 get_random_bytes(protkey, keysize); 367 368out: 369 pr_debug("rc=%d\n", rc); 370 return rc; 371} 372 373/* 374 * Verify a protected key token blob. 375 * Currently only AES protected keys are supported. 376 */ 377static int pckmo_verify_key(const u8 *key, u32 keylen) 378{ 379 struct keytoken_header *hdr = (struct keytoken_header *)key; 380 int rc = -EINVAL; 381 382 if (keylen < sizeof(*hdr)) 383 return -EINVAL; 384 if (hdr->type != TOKTYPE_NON_CCA) 385 return -EINVAL; 386 387 switch (hdr->version) { 388 case TOKVER_PROTECTED_KEY: { 389 struct protaeskeytoken *t; 390 391 if (keylen != sizeof(struct protaeskeytoken)) 392 goto out; 393 t = (struct protaeskeytoken *)key; 394 rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype); 395 break; 396 } 397 default: 398 PKEY_DBF_ERR("%s unknown non-CCA token version %d\n", 399 __func__, hdr->version); 400 break; 401 } 402 403out: 404 pr_debug("rc=%d\n", rc); 405 return rc; 406} 407 408/* 409 * Wrapper functions used for the pkey handler struct 410 */ 411 412static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns, 413 size_t _nr_apqns, 414 const u8 *key, u32 keylen, 415 u8 *protkey, u32 *protkeylen, u32 *keyinfo) 416{ 417 return pckmo_key2protkey(key, keylen, 418 protkey, protkeylen, keyinfo); 419} 420 421static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns, 422 u32 keytype, u32 keysubtype, 423 u32 _keybitsize, u32 _flags, 424 u8 *keybuf, u32 *keybuflen, u32 *keyinfo) 425{ 426 return pckmo_gen_protkey(keytype, keysubtype, 427 keybuf, keybuflen, keyinfo); 428} 429 430static int pkey_pckmo_verifykey(const u8 *key, u32 keylen, 431 u16 *_card, u16 *_dom, 432 u32 *_keytype, u32 *_keybitsize, u32 *_flags) 433{ 434 return pckmo_verify_key(key, keylen); 435} 436 437static struct pkey_handler pckmo_handler = { 438 .module = THIS_MODULE, 439 .name = "PKEY PCKMO handler", 440 .is_supported_key = is_pckmo_key, 441 .is_supported_keytype = is_pckmo_keytype, 442 .key_to_protkey = pkey_pckmo_key2protkey, 443 .gen_key = pkey_pckmo_gen_key, 444 .verify_key = pkey_pckmo_verifykey, 445}; 446 447/* 448 * Module init 449 */ 450static int __init pkey_pckmo_init(void) 451{ 452 cpacf_mask_t func_mask; 453 454 /* 455 * The pckmo instruction should be available - even if we don't 456 * actually invoke it. This instruction comes with MSA 3 which 457 * is also the minimum level for the kmc instructions which 458 * are able to work with protected keys. 459 */ 460 if (!cpacf_query(CPACF_PCKMO, &func_mask)) 461 return -ENODEV; 462 463 /* register this module as pkey handler for all the pckmo stuff */ 464 return pkey_handler_register(&pckmo_handler); 465} 466 467/* 468 * Module exit 469 */ 470static void __exit pkey_pckmo_exit(void) 471{ 472 /* unregister this module as pkey handler */ 473 pkey_handler_unregister(&pckmo_handler); 474} 475 476module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_pckmo_init); 477module_exit(pkey_pckmo_exit); |
|