static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); cpacf_km(CPACF_KM_DEA | CPACF_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE); }
static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); cpacf_km(CPACF_KM_TDEA_192 | CPACF_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); }
static int ecb_desall_crypt(struct blkcipher_desc *desc, unsigned long fc, struct blkcipher_walk *walk) { struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int nbytes, n; int ret; ret = blkcipher_walk_virt(desc, walk); while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { /* only use complete blocks */ n = nbytes & ~(DES_BLOCK_SIZE - 1); cpacf_km(fc, ctx->key, walk->dst.virt.addr, walk->src.virt.addr, n); ret = blkcipher_walk_done(desc, walk, nbytes - n); } return ret; }
static int xts_paes_crypt(struct blkcipher_desc *desc, unsigned long modifier, struct blkcipher_walk *walk) { struct s390_pxts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int keylen, offset, nbytes, n, k; int ret; struct { u8 key[MAXPROTKEYSIZE]; /* key + verification pattern */ u8 tweak[16]; u8 block[16]; u8 bit[16]; u8 xts[16]; } pcc_param; struct { u8 key[MAXPROTKEYSIZE]; /* key + verification pattern */ u8 init[16]; } xts_param; ret = blkcipher_walk_virt(desc, walk); keylen = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 48 : 64; offset = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 16 : 0; retry: memset(&pcc_param, 0, sizeof(pcc_param)); memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak)); memcpy(pcc_param.key + offset, ctx->pk[1].protkey, keylen); cpacf_pcc(ctx->fc, pcc_param.key + offset); memcpy(xts_param.key + offset, ctx->pk[0].protkey, keylen); memcpy(xts_param.init, pcc_param.xts, 16); while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); k = cpacf_km(ctx->fc | modifier, xts_param.key + offset, walk->dst.virt.addr, walk->src.virt.addr, n); if (k) ret = blkcipher_walk_done(desc, walk, nbytes - k); if (k < n) { if (__xts_paes_set_key(ctx) != 0) return blkcipher_walk_done(desc, walk, -EIO); goto retry; } } return ret; }
static int ecb_paes_crypt(struct blkcipher_desc *desc, unsigned long modifier, struct blkcipher_walk *walk) { struct s390_paes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int nbytes, n, k; int ret; ret = blkcipher_walk_virt(desc, walk); while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); k = cpacf_km(ctx->fc | modifier, ctx->pk.protkey, walk->dst.virt.addr, walk->src.virt.addr, n); if (k) ret = blkcipher_walk_done(desc, walk, nbytes - k); if (k < n) { if (__paes_set_key(ctx) != 0) return blkcipher_walk_done(desc, walk, -EIO); } } return ret; }