/* * Create a protected key from a clear key value. */ int pkey_clr2protkey(u32 keytype, const struct pkey_clrkey *clrkey, struct pkey_protkey *protkey) { long fc; int keysize; u8 paramblock[64]; switch (keytype) { case PKEY_KEYTYPE_AES_128: keysize = 16; fc = CPACF_PCKMO_ENC_AES_128_KEY; break; case PKEY_KEYTYPE_AES_192: keysize = 24; fc = CPACF_PCKMO_ENC_AES_192_KEY; break; case PKEY_KEYTYPE_AES_256: keysize = 32; fc = CPACF_PCKMO_ENC_AES_256_KEY; break; default: DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__, keytype); return -EINVAL; } /* * Check if the needed pckmo subfunction is available. * These subfunctions can be enabled/disabled by customers * in the LPAR profile or may even change on the fly. */ if (!cpacf_test_func(&pckmo_functions, fc)) { DEBUG_ERR("%s pckmo functions not available\n", __func__); return -EOPNOTSUPP; } /* prepare param block */ memset(paramblock, 0, sizeof(paramblock)); memcpy(paramblock, clrkey->clrkey, keysize); /* call the pckmo instruction */ cpacf_pckmo(fc, paramblock); /* copy created protected key */ protkey->type = keytype; protkey->len = keysize + 32; memcpy(protkey->protkey, paramblock, keysize + 32); return 0; }
static int __paes_set_key(struct s390_paes_ctx *ctx) { unsigned long fc; if (__paes_convert_key(&ctx->sk, &ctx->pk)) return -EINVAL; /* Pick the correct function code based on the protected key type */ fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 : (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 : (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0; /* Check if the function code is available */ ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0; return ctx->fc ? 0 : -EINVAL; }
static int __init paes_s390_init(void) { int ret; /* Query available functions for KM, KMC and KMCTR */ cpacf_query(CPACF_KM, &km_functions); cpacf_query(CPACF_KMC, &kmc_functions); cpacf_query(CPACF_KMCTR, &kmctr_functions); if (cpacf_test_func(&km_functions, CPACF_KM_PAES_128) || cpacf_test_func(&km_functions, CPACF_KM_PAES_192) || cpacf_test_func(&km_functions, CPACF_KM_PAES_256)) { ret = crypto_register_alg(&ecb_paes_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_128) || cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_192) || cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_256)) { ret = crypto_register_alg(&cbc_paes_alg); if (ret) goto out_err; } if (cpacf_test_func(&km_functions, CPACF_KM_PXTS_128) || cpacf_test_func(&km_functions, CPACF_KM_PXTS_256)) { ret = crypto_register_alg(&xts_paes_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_128) || cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_192) || cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_256)) { ret = crypto_register_alg(&ctr_paes_alg); if (ret) goto out_err; ctrblk = (u8 *) __get_free_page(GFP_KERNEL); if (!ctrblk) { ret = -ENOMEM; goto out_err; } } return 0; out_err: paes_s390_fini(); return ret; }
static int __init des_s390_init(void) { int ret; /* Query available functions for KM, KMC and KMCTR */ cpacf_query(CPACF_KM, &km_functions); cpacf_query(CPACF_KMC, &kmc_functions); cpacf_query(CPACF_KMCTR, &kmctr_functions); if (cpacf_test_func(&km_functions, CPACF_KM_DEA)) { ret = des_s390_register_alg(&des_alg); if (ret) goto out_err; ret = des_s390_register_alg(&ecb_des_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmc_functions, CPACF_KMC_DEA)) { ret = des_s390_register_alg(&cbc_des_alg); if (ret) goto out_err; } if (cpacf_test_func(&km_functions, CPACF_KM_TDEA_192)) { ret = des_s390_register_alg(&des3_alg); if (ret) goto out_err; ret = des_s390_register_alg(&ecb_des3_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmc_functions, CPACF_KMC_TDEA_192)) { ret = des_s390_register_alg(&cbc_des3_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_DEA) || cpacf_test_func(&kmctr_functions, CPACF_KMCTR_TDEA_192)) { ctrblk = (u8 *) __get_free_page(GFP_KERNEL); if (!ctrblk) { ret = -ENOMEM; goto out_err; } } if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_DEA)) { ret = des_s390_register_alg(&ctr_des_alg); if (ret) goto out_err; } if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_TDEA_192)) { ret = des_s390_register_alg(&ctr_des3_alg); if (ret) goto out_err; } return 0; out_err: des_s390_exit(); return ret; }