static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, DES3_192_BLOCK_SIZE); }
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); switch (sctx->key_len) { case 16: crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; case 24: crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; case 32: crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; } }
static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); int ret; /* only use complete blocks */ nbytes &= ~(DES_BLOCK_SIZE - 1); ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes); BUG_ON((ret < 0) || (ret != nbytes)); return nbytes; }
static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); if (unlikely(need_fallback(sctx->key_len))) { crypto_cipher_decrypt_one(sctx->fallback.cip, out, in); return; } switch (sctx->key_len) { case 16: crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; case 24: crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; case 32: crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, AES_BLOCK_SIZE); break; } }
static int xts_aes_crypt(struct blkcipher_desc *desc, long func, struct s390_xts_ctx *xts_ctx, struct blkcipher_walk *walk) { unsigned int offset = (xts_ctx->key_len >> 1) & 0x10; int ret = blkcipher_walk_virt(desc, walk); unsigned int nbytes = walk->nbytes; unsigned int n; u8 *in, *out; struct pcc_param pcc_param; struct { u8 key[32]; u8 init[16]; } xts_param; if (!nbytes) goto out; memset(pcc_param.block, 0, sizeof(pcc_param.block)); memset(pcc_param.bit, 0, sizeof(pcc_param.bit)); memset(pcc_param.xts, 0, sizeof(pcc_param.xts)); memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak)); memcpy(pcc_param.key, xts_ctx->pcc_key, 32); ret = crypt_s390_pcc(func, &pcc_param.key[offset]); if (ret < 0) return -EIO; memcpy(xts_param.key, xts_ctx->key, 32); memcpy(xts_param.init, pcc_param.xts, 16); do { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); out = walk->dst.virt.addr; in = walk->src.virt.addr; ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n); if (ret < 0 || ret != n) return -EIO; nbytes &= AES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, walk, nbytes); } while ((nbytes = walk->nbytes)); out: return ret; }
static int init(void) { struct crypt_s390_query_status status = { .high = 0, .low = 0 }; printk(KERN_INFO "crypt_s390: querying available crypto functions\n"); crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); printk(KERN_INFO "KM:\t%016llx %016llx\n", (unsigned long long) status.high, (unsigned long long) status.low); status.high = status.low = 0; crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); printk(KERN_INFO "KMC:\t%016llx %016llx\n", (unsigned long long) status.high, (unsigned long long) status.low); status.high = status.low = 0; crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); printk(KERN_INFO "KIMD:\t%016llx %016llx\n", (unsigned long long) status.high, (unsigned long long) status.low); status.high = status.low = 0; crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); printk(KERN_INFO "KLMD:\t%016llx %016llx\n", (unsigned long long) status.high, (unsigned long long) status.low); status.high = status.low = 0; crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); printk(KERN_INFO "KMAC:\t%016llx %016llx\n", (unsigned long long) status.high, (unsigned long long) status.low); query_available_functions(); return -ECANCELED; } static void __exit cleanup(void) { } module_init(init); module_exit(cleanup); MODULE_LICENSE("GPL");
static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param, struct blkcipher_walk *walk) { int ret = blkcipher_walk_virt(desc, walk); unsigned int nbytes; while ((nbytes = walk->nbytes)) { /* only use complete blocks */ unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1); u8 *out = walk->dst.virt.addr; u8 *in = walk->src.virt.addr; ret = crypt_s390_km(func, param, out, in, n); BUG_ON((ret < 0) || (ret != n)); nbytes &= AES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, walk, nbytes); } return ret; }
static int xts_aes_crypt(struct blkcipher_desc *desc, long func, struct s390_xts_ctx *xts_ctx, struct blkcipher_walk *walk) { unsigned int offset = (xts_ctx->key_len >> 1) & 0x10; int ret = blkcipher_walk_virt(desc, walk); unsigned int nbytes = walk->nbytes; unsigned int n; u8 *in, *out; void *param; if (!nbytes) goto out; memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block)); memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit)); memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts)); memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak)); param = xts_ctx->pcc.key + offset; ret = crypt_s390_pcc(func, param); BUG_ON(ret < 0); memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16); param = xts_ctx->key + offset; do { n = nbytes & ~(AES_BLOCK_SIZE - 1); out = walk->dst.virt.addr; in = walk->src.virt.addr; ret = crypt_s390_km(func, param, out, in, n); BUG_ON(ret < 0 || ret != n); nbytes &= AES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, walk, nbytes); } while ((nbytes = walk->nbytes)); out: return ret; }
static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, u8 *key, struct blkcipher_walk *walk) { int ret = blkcipher_walk_virt(desc, walk); unsigned int nbytes; while ((nbytes = walk->nbytes)) { /* only use complete blocks */ unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); u8 *out = walk->dst.virt.addr; u8 *in = walk->src.virt.addr; ret = crypt_s390_km(func, key, out, in, n); if (ret < 0 || ret != n) return -EIO; nbytes &= DES_BLOCK_SIZE - 1; ret = blkcipher_walk_done(desc, walk, nbytes); } return ret; }
static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE); }
static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); }