1c1e26e1eSJan Glauber /* 2c1e26e1eSJan Glauber * Cryptographic API. 3c1e26e1eSJan Glauber * 4c1e26e1eSJan Glauber * s390 implementation of the DES Cipher Algorithm. 5c1e26e1eSJan Glauber * 60200f3ecSGerald Schaefer * Copyright IBM Corp. 2003, 2011 786aa9fc2SJan Glauber * Author(s): Thomas Spatzier 886aa9fc2SJan Glauber * Jan Glauber (jan.glauber@de.ibm.com) 9c1e26e1eSJan Glauber * 10c1e26e1eSJan Glauber * This program is free software; you can redistribute it and/or modify 11c1e26e1eSJan Glauber * it under the terms of the GNU General Public License as published by 12c1e26e1eSJan Glauber * the Free Software Foundation; either version 2 of the License, or 13c1e26e1eSJan Glauber * (at your option) any later version. 14c1e26e1eSJan Glauber * 15c1e26e1eSJan Glauber */ 16a9e62fadSHerbert Xu 17c1e26e1eSJan Glauber #include <linux/init.h> 18c1e26e1eSJan Glauber #include <linux/module.h> 191efbd15cSJan Glauber #include <linux/crypto.h> 201efbd15cSJan Glauber #include <crypto/algapi.h> 211efbd15cSJan Glauber #include <crypto/des.h> 22c1357833SJan Glauber 23c1e26e1eSJan Glauber #include "crypt_s390.h" 24c1e26e1eSJan Glauber 2598971f84SJan Glauber #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) 26c1e26e1eSJan Glauber 270200f3ecSGerald Schaefer static u8 *ctrblk; 280200f3ecSGerald Schaefer 2998971f84SJan Glauber struct s390_des_ctx { 30c1e26e1eSJan Glauber u8 iv[DES_BLOCK_SIZE]; 3198971f84SJan Glauber u8 key[DES3_KEY_SIZE]; 32c1e26e1eSJan Glauber }; 33c1e26e1eSJan Glauber 346c2bb98bSHerbert Xu static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 3598971f84SJan Glauber unsigned int key_len) 36c1e26e1eSJan Glauber { 3798971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 38560c06aeSHerbert Xu u32 *flags = &tfm->crt_flags; 391efbd15cSJan Glauber u32 tmp[DES_EXPKEY_WORDS]; 40c1e26e1eSJan Glauber 411efbd15cSJan Glauber /* check for weak keys */ 421efbd15cSJan Glauber if (!des_ekey(tmp, key) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { 431efbd15cSJan Glauber *flags |= CRYPTO_TFM_RES_WEAK_KEY; 441efbd15cSJan Glauber return -EINVAL; 451efbd15cSJan Glauber } 461efbd15cSJan Glauber 4798971f84SJan Glauber memcpy(ctx->key, key, key_len); 481efbd15cSJan Glauber return 0; 49c1e26e1eSJan Glauber } 50c1e26e1eSJan Glauber 516c2bb98bSHerbert Xu static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 52c1e26e1eSJan Glauber { 5398971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 54c1e26e1eSJan Glauber 5598971f84SJan Glauber crypt_s390_km(KM_DEA_ENCRYPT, ctx->key, out, in, DES_BLOCK_SIZE); 56c1e26e1eSJan Glauber } 57c1e26e1eSJan Glauber 586c2bb98bSHerbert Xu static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 59c1e26e1eSJan Glauber { 6098971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 61c1e26e1eSJan Glauber 6298971f84SJan Glauber crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE); 63b8dc6038SJan Glauber } 64b8dc6038SJan Glauber 65c1e26e1eSJan Glauber static struct crypto_alg des_alg = { 66c1e26e1eSJan Glauber .cra_name = "des", 6765b75c36SHerbert Xu .cra_driver_name = "des-s390", 6865b75c36SHerbert Xu .cra_priority = CRYPT_S390_PRIORITY, 69c1e26e1eSJan Glauber .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 70c1e26e1eSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 7198971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 72c1e26e1eSJan Glauber .cra_module = THIS_MODULE, 73c1357833SJan Glauber .cra_u = { 74c1357833SJan Glauber .cipher = { 75c1e26e1eSJan Glauber .cia_min_keysize = DES_KEY_SIZE, 76c1e26e1eSJan Glauber .cia_max_keysize = DES_KEY_SIZE, 77c1e26e1eSJan Glauber .cia_setkey = des_setkey, 78c1e26e1eSJan Glauber .cia_encrypt = des_encrypt, 79b8dc6038SJan Glauber .cia_decrypt = des_decrypt, 80c1357833SJan Glauber } 81c1357833SJan Glauber } 82c1e26e1eSJan Glauber }; 83c1e26e1eSJan Glauber 84a9e62fadSHerbert Xu static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, 8598971f84SJan Glauber u8 *key, struct blkcipher_walk *walk) 86a9e62fadSHerbert Xu { 87a9e62fadSHerbert Xu int ret = blkcipher_walk_virt(desc, walk); 88a9e62fadSHerbert Xu unsigned int nbytes; 89a9e62fadSHerbert Xu 90a9e62fadSHerbert Xu while ((nbytes = walk->nbytes)) { 91a9e62fadSHerbert Xu /* only use complete blocks */ 92a9e62fadSHerbert Xu unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); 93a9e62fadSHerbert Xu u8 *out = walk->dst.virt.addr; 94a9e62fadSHerbert Xu u8 *in = walk->src.virt.addr; 95a9e62fadSHerbert Xu 9698971f84SJan Glauber ret = crypt_s390_km(func, key, out, in, n); 9736eb2caaSJan Glauber if (ret < 0 || ret != n) 9836eb2caaSJan Glauber return -EIO; 99a9e62fadSHerbert Xu 100a9e62fadSHerbert Xu nbytes &= DES_BLOCK_SIZE - 1; 101a9e62fadSHerbert Xu ret = blkcipher_walk_done(desc, walk, nbytes); 102a9e62fadSHerbert Xu } 103a9e62fadSHerbert Xu 104a9e62fadSHerbert Xu return ret; 105a9e62fadSHerbert Xu } 106a9e62fadSHerbert Xu 107a9e62fadSHerbert Xu static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, 10898971f84SJan Glauber u8 *iv, struct blkcipher_walk *walk) 109a9e62fadSHerbert Xu { 110a9e62fadSHerbert Xu int ret = blkcipher_walk_virt(desc, walk); 111a9e62fadSHerbert Xu unsigned int nbytes = walk->nbytes; 112a9e62fadSHerbert Xu 113a9e62fadSHerbert Xu if (!nbytes) 114a9e62fadSHerbert Xu goto out; 115a9e62fadSHerbert Xu 11698971f84SJan Glauber memcpy(iv, walk->iv, DES_BLOCK_SIZE); 117a9e62fadSHerbert Xu do { 118a9e62fadSHerbert Xu /* only use complete blocks */ 119a9e62fadSHerbert Xu unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); 120a9e62fadSHerbert Xu u8 *out = walk->dst.virt.addr; 121a9e62fadSHerbert Xu u8 *in = walk->src.virt.addr; 122a9e62fadSHerbert Xu 12398971f84SJan Glauber ret = crypt_s390_kmc(func, iv, out, in, n); 12436eb2caaSJan Glauber if (ret < 0 || ret != n) 12536eb2caaSJan Glauber return -EIO; 126a9e62fadSHerbert Xu 127a9e62fadSHerbert Xu nbytes &= DES_BLOCK_SIZE - 1; 128a9e62fadSHerbert Xu ret = blkcipher_walk_done(desc, walk, nbytes); 129a9e62fadSHerbert Xu } while ((nbytes = walk->nbytes)); 13098971f84SJan Glauber memcpy(walk->iv, iv, DES_BLOCK_SIZE); 131a9e62fadSHerbert Xu 132a9e62fadSHerbert Xu out: 133a9e62fadSHerbert Xu return ret; 134a9e62fadSHerbert Xu } 135a9e62fadSHerbert Xu 136a9e62fadSHerbert Xu static int ecb_des_encrypt(struct blkcipher_desc *desc, 137a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 138a9e62fadSHerbert Xu unsigned int nbytes) 139a9e62fadSHerbert Xu { 14098971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 141a9e62fadSHerbert Xu struct blkcipher_walk walk; 142a9e62fadSHerbert Xu 143a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 14498971f84SJan Glauber return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, ctx->key, &walk); 145a9e62fadSHerbert Xu } 146a9e62fadSHerbert Xu 147a9e62fadSHerbert Xu static int ecb_des_decrypt(struct blkcipher_desc *desc, 148a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 149a9e62fadSHerbert Xu unsigned int nbytes) 150a9e62fadSHerbert Xu { 15198971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 152a9e62fadSHerbert Xu struct blkcipher_walk walk; 153a9e62fadSHerbert Xu 154a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 15598971f84SJan Glauber return ecb_desall_crypt(desc, KM_DEA_DECRYPT, ctx->key, &walk); 156a9e62fadSHerbert Xu } 157a9e62fadSHerbert Xu 158a9e62fadSHerbert Xu static struct crypto_alg ecb_des_alg = { 159a9e62fadSHerbert Xu .cra_name = "ecb(des)", 160a9e62fadSHerbert Xu .cra_driver_name = "ecb-des-s390", 161a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 162a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 163a9e62fadSHerbert Xu .cra_blocksize = DES_BLOCK_SIZE, 16498971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 165a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 166a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 167a9e62fadSHerbert Xu .cra_u = { 168a9e62fadSHerbert Xu .blkcipher = { 169a9e62fadSHerbert Xu .min_keysize = DES_KEY_SIZE, 170a9e62fadSHerbert Xu .max_keysize = DES_KEY_SIZE, 171a9e62fadSHerbert Xu .setkey = des_setkey, 172a9e62fadSHerbert Xu .encrypt = ecb_des_encrypt, 173a9e62fadSHerbert Xu .decrypt = ecb_des_decrypt, 174a9e62fadSHerbert Xu } 175a9e62fadSHerbert Xu } 176a9e62fadSHerbert Xu }; 177a9e62fadSHerbert Xu 178a9e62fadSHerbert Xu static int cbc_des_encrypt(struct blkcipher_desc *desc, 179a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 180a9e62fadSHerbert Xu unsigned int nbytes) 181a9e62fadSHerbert Xu { 18298971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 183a9e62fadSHerbert Xu struct blkcipher_walk walk; 184a9e62fadSHerbert Xu 185a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 18698971f84SJan Glauber return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk); 187a9e62fadSHerbert Xu } 188a9e62fadSHerbert Xu 189a9e62fadSHerbert Xu static int cbc_des_decrypt(struct blkcipher_desc *desc, 190a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 191a9e62fadSHerbert Xu unsigned int nbytes) 192a9e62fadSHerbert Xu { 19398971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 194a9e62fadSHerbert Xu struct blkcipher_walk walk; 195a9e62fadSHerbert Xu 196a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 19798971f84SJan Glauber return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk); 198a9e62fadSHerbert Xu } 199a9e62fadSHerbert Xu 200a9e62fadSHerbert Xu static struct crypto_alg cbc_des_alg = { 201a9e62fadSHerbert Xu .cra_name = "cbc(des)", 202a9e62fadSHerbert Xu .cra_driver_name = "cbc-des-s390", 203a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 204a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 205a9e62fadSHerbert Xu .cra_blocksize = DES_BLOCK_SIZE, 20698971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 207a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 208a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 209a9e62fadSHerbert Xu .cra_u = { 210a9e62fadSHerbert Xu .blkcipher = { 211a9e62fadSHerbert Xu .min_keysize = DES_KEY_SIZE, 212a9e62fadSHerbert Xu .max_keysize = DES_KEY_SIZE, 213a9e62fadSHerbert Xu .ivsize = DES_BLOCK_SIZE, 214a9e62fadSHerbert Xu .setkey = des_setkey, 215a9e62fadSHerbert Xu .encrypt = cbc_des_encrypt, 216a9e62fadSHerbert Xu .decrypt = cbc_des_decrypt, 217a9e62fadSHerbert Xu } 218a9e62fadSHerbert Xu } 219a9e62fadSHerbert Xu }; 220a9e62fadSHerbert Xu 221c1e26e1eSJan Glauber /* 222c1e26e1eSJan Glauber * RFC2451: 223c1e26e1eSJan Glauber * 224c1e26e1eSJan Glauber * For DES-EDE3, there is no known need to reject weak or 225c1e26e1eSJan Glauber * complementation keys. Any weakness is obviated by the use of 226c1e26e1eSJan Glauber * multiple keys. 227c1e26e1eSJan Glauber * 228c1e26e1eSJan Glauber * However, if the first two or last two independent 64-bit keys are 229c1e26e1eSJan Glauber * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the 230c1e26e1eSJan Glauber * same as DES. Implementers MUST reject keys that exhibit this 231c1e26e1eSJan Glauber * property. 232c1e26e1eSJan Glauber * 233c1e26e1eSJan Glauber */ 23498971f84SJan Glauber static int des3_setkey(struct crypto_tfm *tfm, const u8 *key, 23598971f84SJan Glauber unsigned int key_len) 236c1e26e1eSJan Glauber { 23798971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 238560c06aeSHerbert Xu u32 *flags = &tfm->crt_flags; 239c1e26e1eSJan Glauber 240fed28611SDaniel Borkmann if (!(crypto_memneq(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 241fed28611SDaniel Borkmann crypto_memneq(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], 24203b56ce5SJarod Wilson DES_KEY_SIZE)) && 24303b56ce5SJarod Wilson (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { 24403b56ce5SJarod Wilson *flags |= CRYPTO_TFM_RES_WEAK_KEY; 245c1e26e1eSJan Glauber return -EINVAL; 246c1e26e1eSJan Glauber } 24798971f84SJan Glauber memcpy(ctx->key, key, key_len); 248c1e26e1eSJan Glauber return 0; 249c1e26e1eSJan Glauber } 250c1e26e1eSJan Glauber 25198971f84SJan Glauber static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 252c1e26e1eSJan Glauber { 25398971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 254c1e26e1eSJan Glauber 25598971f84SJan Glauber crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); 256c1e26e1eSJan Glauber } 257c1e26e1eSJan Glauber 25898971f84SJan Glauber static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 259c1e26e1eSJan Glauber { 26098971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 261c1e26e1eSJan Glauber 26298971f84SJan Glauber crypt_s390_km(KM_TDEA_192_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); 263c1e26e1eSJan Glauber } 264c1e26e1eSJan Glauber 26598971f84SJan Glauber static struct crypto_alg des3_alg = { 266c1e26e1eSJan Glauber .cra_name = "des3_ede", 26765b75c36SHerbert Xu .cra_driver_name = "des3_ede-s390", 26865b75c36SHerbert Xu .cra_priority = CRYPT_S390_PRIORITY, 269c1e26e1eSJan Glauber .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 2701efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 27198971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 272c1e26e1eSJan Glauber .cra_module = THIS_MODULE, 273c1357833SJan Glauber .cra_u = { 274c1357833SJan Glauber .cipher = { 27598971f84SJan Glauber .cia_min_keysize = DES3_KEY_SIZE, 27698971f84SJan Glauber .cia_max_keysize = DES3_KEY_SIZE, 27798971f84SJan Glauber .cia_setkey = des3_setkey, 27898971f84SJan Glauber .cia_encrypt = des3_encrypt, 27998971f84SJan Glauber .cia_decrypt = des3_decrypt, 280c1357833SJan Glauber } 281c1357833SJan Glauber } 282c1e26e1eSJan Glauber }; 283c1e26e1eSJan Glauber 28498971f84SJan Glauber static int ecb_des3_encrypt(struct blkcipher_desc *desc, 28598971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 28698971f84SJan Glauber unsigned int nbytes) 287a9e62fadSHerbert Xu { 28898971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 289a9e62fadSHerbert Xu struct blkcipher_walk walk; 290a9e62fadSHerbert Xu 291a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 29298971f84SJan Glauber return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, ctx->key, &walk); 293a9e62fadSHerbert Xu } 294a9e62fadSHerbert Xu 29598971f84SJan Glauber static int ecb_des3_decrypt(struct blkcipher_desc *desc, 29698971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 29798971f84SJan Glauber unsigned int nbytes) 298a9e62fadSHerbert Xu { 29998971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 300a9e62fadSHerbert Xu struct blkcipher_walk walk; 301a9e62fadSHerbert Xu 302a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 30398971f84SJan Glauber return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, ctx->key, &walk); 304a9e62fadSHerbert Xu } 305a9e62fadSHerbert Xu 30698971f84SJan Glauber static struct crypto_alg ecb_des3_alg = { 307a9e62fadSHerbert Xu .cra_name = "ecb(des3_ede)", 308a9e62fadSHerbert Xu .cra_driver_name = "ecb-des3_ede-s390", 309a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 310a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 3111efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 31298971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 313a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 314a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 315a9e62fadSHerbert Xu .cra_u = { 316a9e62fadSHerbert Xu .blkcipher = { 31798971f84SJan Glauber .min_keysize = DES3_KEY_SIZE, 31898971f84SJan Glauber .max_keysize = DES3_KEY_SIZE, 31998971f84SJan Glauber .setkey = des3_setkey, 32098971f84SJan Glauber .encrypt = ecb_des3_encrypt, 32198971f84SJan Glauber .decrypt = ecb_des3_decrypt, 322a9e62fadSHerbert Xu } 323a9e62fadSHerbert Xu } 324a9e62fadSHerbert Xu }; 325a9e62fadSHerbert Xu 32698971f84SJan Glauber static int cbc_des3_encrypt(struct blkcipher_desc *desc, 32798971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 32898971f84SJan Glauber unsigned int nbytes) 329a9e62fadSHerbert Xu { 33098971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 331a9e62fadSHerbert Xu struct blkcipher_walk walk; 332a9e62fadSHerbert Xu 333a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 33498971f84SJan Glauber return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk); 335a9e62fadSHerbert Xu } 336a9e62fadSHerbert Xu 33798971f84SJan Glauber static int cbc_des3_decrypt(struct blkcipher_desc *desc, 33898971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 33998971f84SJan Glauber unsigned int nbytes) 340a9e62fadSHerbert Xu { 34198971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 342a9e62fadSHerbert Xu struct blkcipher_walk walk; 343a9e62fadSHerbert Xu 344a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 34598971f84SJan Glauber return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk); 346a9e62fadSHerbert Xu } 347a9e62fadSHerbert Xu 34898971f84SJan Glauber static struct crypto_alg cbc_des3_alg = { 349a9e62fadSHerbert Xu .cra_name = "cbc(des3_ede)", 350a9e62fadSHerbert Xu .cra_driver_name = "cbc-des3_ede-s390", 351a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 352a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 3531efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 35498971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 355a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 356a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 357a9e62fadSHerbert Xu .cra_u = { 358a9e62fadSHerbert Xu .blkcipher = { 35998971f84SJan Glauber .min_keysize = DES3_KEY_SIZE, 36098971f84SJan Glauber .max_keysize = DES3_KEY_SIZE, 3611efbd15cSJan Glauber .ivsize = DES_BLOCK_SIZE, 36298971f84SJan Glauber .setkey = des3_setkey, 36398971f84SJan Glauber .encrypt = cbc_des3_encrypt, 36498971f84SJan Glauber .decrypt = cbc_des3_decrypt, 365a9e62fadSHerbert Xu } 366a9e62fadSHerbert Xu } 367a9e62fadSHerbert Xu }; 368a9e62fadSHerbert Xu 3690200f3ecSGerald Schaefer static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, 3700200f3ecSGerald Schaefer struct s390_des_ctx *ctx, struct blkcipher_walk *walk) 3710200f3ecSGerald Schaefer { 3720200f3ecSGerald Schaefer int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); 3730200f3ecSGerald Schaefer unsigned int i, n, nbytes; 3740200f3ecSGerald Schaefer u8 buf[DES_BLOCK_SIZE]; 3750200f3ecSGerald Schaefer u8 *out, *in; 3760200f3ecSGerald Schaefer 3770200f3ecSGerald Schaefer memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE); 3780200f3ecSGerald Schaefer while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { 3790200f3ecSGerald Schaefer out = walk->dst.virt.addr; 3800200f3ecSGerald Schaefer in = walk->src.virt.addr; 3810200f3ecSGerald Schaefer while (nbytes >= DES_BLOCK_SIZE) { 3820200f3ecSGerald Schaefer /* align to block size, max. PAGE_SIZE */ 3830200f3ecSGerald Schaefer n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : 3840200f3ecSGerald Schaefer nbytes & ~(DES_BLOCK_SIZE - 1); 3850200f3ecSGerald Schaefer for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { 3860200f3ecSGerald Schaefer memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE, 3870200f3ecSGerald Schaefer DES_BLOCK_SIZE); 3880200f3ecSGerald Schaefer crypto_inc(ctrblk + i, DES_BLOCK_SIZE); 3890200f3ecSGerald Schaefer } 3900200f3ecSGerald Schaefer ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); 39136eb2caaSJan Glauber if (ret < 0 || ret != n) 39236eb2caaSJan Glauber return -EIO; 3930200f3ecSGerald Schaefer if (n > DES_BLOCK_SIZE) 3940200f3ecSGerald Schaefer memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, 3950200f3ecSGerald Schaefer DES_BLOCK_SIZE); 3960200f3ecSGerald Schaefer crypto_inc(ctrblk, DES_BLOCK_SIZE); 3970200f3ecSGerald Schaefer out += n; 3980200f3ecSGerald Schaefer in += n; 3990200f3ecSGerald Schaefer nbytes -= n; 4000200f3ecSGerald Schaefer } 4010200f3ecSGerald Schaefer ret = blkcipher_walk_done(desc, walk, nbytes); 4020200f3ecSGerald Schaefer } 4030200f3ecSGerald Schaefer 4040200f3ecSGerald Schaefer /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ 4050200f3ecSGerald Schaefer if (nbytes) { 4060200f3ecSGerald Schaefer out = walk->dst.virt.addr; 4070200f3ecSGerald Schaefer in = walk->src.virt.addr; 4080200f3ecSGerald Schaefer ret = crypt_s390_kmctr(func, ctx->key, buf, in, 4090200f3ecSGerald Schaefer DES_BLOCK_SIZE, ctrblk); 41036eb2caaSJan Glauber if (ret < 0 || ret != DES_BLOCK_SIZE) 41136eb2caaSJan Glauber return -EIO; 4120200f3ecSGerald Schaefer memcpy(out, buf, nbytes); 4130200f3ecSGerald Schaefer crypto_inc(ctrblk, DES_BLOCK_SIZE); 4140200f3ecSGerald Schaefer ret = blkcipher_walk_done(desc, walk, 0); 4150200f3ecSGerald Schaefer } 4160200f3ecSGerald Schaefer memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE); 4170200f3ecSGerald Schaefer return ret; 4180200f3ecSGerald Schaefer } 4190200f3ecSGerald Schaefer 4200200f3ecSGerald Schaefer static int ctr_des_encrypt(struct blkcipher_desc *desc, 4210200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4220200f3ecSGerald Schaefer unsigned int nbytes) 4230200f3ecSGerald Schaefer { 4240200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 4250200f3ecSGerald Schaefer struct blkcipher_walk walk; 4260200f3ecSGerald Schaefer 4270200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 4280200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_DEA_ENCRYPT, ctx, &walk); 4290200f3ecSGerald Schaefer } 4300200f3ecSGerald Schaefer 4310200f3ecSGerald Schaefer static int ctr_des_decrypt(struct blkcipher_desc *desc, 4320200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4330200f3ecSGerald Schaefer unsigned int nbytes) 4340200f3ecSGerald Schaefer { 4350200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 4360200f3ecSGerald Schaefer struct blkcipher_walk walk; 4370200f3ecSGerald Schaefer 4380200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 4390200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_DEA_DECRYPT, ctx, &walk); 4400200f3ecSGerald Schaefer } 4410200f3ecSGerald Schaefer 4420200f3ecSGerald Schaefer static struct crypto_alg ctr_des_alg = { 4430200f3ecSGerald Schaefer .cra_name = "ctr(des)", 4440200f3ecSGerald Schaefer .cra_driver_name = "ctr-des-s390", 4450200f3ecSGerald Schaefer .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 4460200f3ecSGerald Schaefer .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 4470200f3ecSGerald Schaefer .cra_blocksize = 1, 4480200f3ecSGerald Schaefer .cra_ctxsize = sizeof(struct s390_des_ctx), 4490200f3ecSGerald Schaefer .cra_type = &crypto_blkcipher_type, 4500200f3ecSGerald Schaefer .cra_module = THIS_MODULE, 4510200f3ecSGerald Schaefer .cra_u = { 4520200f3ecSGerald Schaefer .blkcipher = { 4530200f3ecSGerald Schaefer .min_keysize = DES_KEY_SIZE, 4540200f3ecSGerald Schaefer .max_keysize = DES_KEY_SIZE, 4550200f3ecSGerald Schaefer .ivsize = DES_BLOCK_SIZE, 4560200f3ecSGerald Schaefer .setkey = des_setkey, 4570200f3ecSGerald Schaefer .encrypt = ctr_des_encrypt, 4580200f3ecSGerald Schaefer .decrypt = ctr_des_decrypt, 4590200f3ecSGerald Schaefer } 4600200f3ecSGerald Schaefer } 4610200f3ecSGerald Schaefer }; 4620200f3ecSGerald Schaefer 4630200f3ecSGerald Schaefer static int ctr_des3_encrypt(struct blkcipher_desc *desc, 4640200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4650200f3ecSGerald Schaefer unsigned int nbytes) 4660200f3ecSGerald Schaefer { 4670200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 4680200f3ecSGerald Schaefer struct blkcipher_walk walk; 4690200f3ecSGerald Schaefer 4700200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 4710200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_TDEA_192_ENCRYPT, ctx, &walk); 4720200f3ecSGerald Schaefer } 4730200f3ecSGerald Schaefer 4740200f3ecSGerald Schaefer static int ctr_des3_decrypt(struct blkcipher_desc *desc, 4750200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4760200f3ecSGerald Schaefer unsigned int nbytes) 4770200f3ecSGerald Schaefer { 4780200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 4790200f3ecSGerald Schaefer struct blkcipher_walk walk; 4800200f3ecSGerald Schaefer 4810200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 4820200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_TDEA_192_DECRYPT, ctx, &walk); 4830200f3ecSGerald Schaefer } 4840200f3ecSGerald Schaefer 4850200f3ecSGerald Schaefer static struct crypto_alg ctr_des3_alg = { 4860200f3ecSGerald Schaefer .cra_name = "ctr(des3_ede)", 4870200f3ecSGerald Schaefer .cra_driver_name = "ctr-des3_ede-s390", 4880200f3ecSGerald Schaefer .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 4890200f3ecSGerald Schaefer .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 4900200f3ecSGerald Schaefer .cra_blocksize = 1, 4910200f3ecSGerald Schaefer .cra_ctxsize = sizeof(struct s390_des_ctx), 4920200f3ecSGerald Schaefer .cra_type = &crypto_blkcipher_type, 4930200f3ecSGerald Schaefer .cra_module = THIS_MODULE, 4940200f3ecSGerald Schaefer .cra_u = { 4950200f3ecSGerald Schaefer .blkcipher = { 4960200f3ecSGerald Schaefer .min_keysize = DES3_KEY_SIZE, 4970200f3ecSGerald Schaefer .max_keysize = DES3_KEY_SIZE, 4980200f3ecSGerald Schaefer .ivsize = DES_BLOCK_SIZE, 4990200f3ecSGerald Schaefer .setkey = des3_setkey, 5000200f3ecSGerald Schaefer .encrypt = ctr_des3_encrypt, 5010200f3ecSGerald Schaefer .decrypt = ctr_des3_decrypt, 5020200f3ecSGerald Schaefer } 5030200f3ecSGerald Schaefer } 5040200f3ecSGerald Schaefer }; 5050200f3ecSGerald Schaefer 50698971f84SJan Glauber static int __init des_s390_init(void) 507c1e26e1eSJan Glauber { 50880d663a4SJan Glauber int ret; 509c1e26e1eSJan Glauber 5101822bc90SJan Glauber if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) || 5111822bc90SJan Glauber !crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA)) 51286aa9fc2SJan Glauber return -EOPNOTSUPP; 513c1e26e1eSJan Glauber 514a9e62fadSHerbert Xu ret = crypto_register_alg(&des_alg); 515a9e62fadSHerbert Xu if (ret) 516a9e62fadSHerbert Xu goto des_err; 517a9e62fadSHerbert Xu ret = crypto_register_alg(&ecb_des_alg); 518a9e62fadSHerbert Xu if (ret) 519a9e62fadSHerbert Xu goto ecb_des_err; 520a9e62fadSHerbert Xu ret = crypto_register_alg(&cbc_des_alg); 521a9e62fadSHerbert Xu if (ret) 522a9e62fadSHerbert Xu goto cbc_des_err; 52398971f84SJan Glauber ret = crypto_register_alg(&des3_alg); 524a9e62fadSHerbert Xu if (ret) 52598971f84SJan Glauber goto des3_err; 52698971f84SJan Glauber ret = crypto_register_alg(&ecb_des3_alg); 527a9e62fadSHerbert Xu if (ret) 52898971f84SJan Glauber goto ecb_des3_err; 52998971f84SJan Glauber ret = crypto_register_alg(&cbc_des3_alg); 530a9e62fadSHerbert Xu if (ret) 53198971f84SJan Glauber goto cbc_des3_err; 5320200f3ecSGerald Schaefer 5330200f3ecSGerald Schaefer if (crypt_s390_func_available(KMCTR_DEA_ENCRYPT, 5340200f3ecSGerald Schaefer CRYPT_S390_MSA | CRYPT_S390_MSA4) && 5350200f3ecSGerald Schaefer crypt_s390_func_available(KMCTR_TDEA_192_ENCRYPT, 5360200f3ecSGerald Schaefer CRYPT_S390_MSA | CRYPT_S390_MSA4)) { 5370200f3ecSGerald Schaefer ret = crypto_register_alg(&ctr_des_alg); 5380200f3ecSGerald Schaefer if (ret) 5390200f3ecSGerald Schaefer goto ctr_des_err; 5400200f3ecSGerald Schaefer ret = crypto_register_alg(&ctr_des3_alg); 5410200f3ecSGerald Schaefer if (ret) 5420200f3ecSGerald Schaefer goto ctr_des3_err; 5430200f3ecSGerald Schaefer ctrblk = (u8 *) __get_free_page(GFP_KERNEL); 5440200f3ecSGerald Schaefer if (!ctrblk) { 5450200f3ecSGerald Schaefer ret = -ENOMEM; 5460200f3ecSGerald Schaefer goto ctr_mem_err; 5470200f3ecSGerald Schaefer } 5480200f3ecSGerald Schaefer } 549a9e62fadSHerbert Xu out: 550a9e62fadSHerbert Xu return ret; 551a9e62fadSHerbert Xu 5520200f3ecSGerald Schaefer ctr_mem_err: 5530200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des3_alg); 5540200f3ecSGerald Schaefer ctr_des3_err: 5550200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des_alg); 5560200f3ecSGerald Schaefer ctr_des_err: 5570200f3ecSGerald Schaefer crypto_unregister_alg(&cbc_des3_alg); 55898971f84SJan Glauber cbc_des3_err: 55998971f84SJan Glauber crypto_unregister_alg(&ecb_des3_alg); 56098971f84SJan Glauber ecb_des3_err: 56198971f84SJan Glauber crypto_unregister_alg(&des3_alg); 56298971f84SJan Glauber des3_err: 563a9e62fadSHerbert Xu crypto_unregister_alg(&cbc_des_alg); 564a9e62fadSHerbert Xu cbc_des_err: 565a9e62fadSHerbert Xu crypto_unregister_alg(&ecb_des_alg); 566a9e62fadSHerbert Xu ecb_des_err: 567c1e26e1eSJan Glauber crypto_unregister_alg(&des_alg); 568a9e62fadSHerbert Xu des_err: 569a9e62fadSHerbert Xu goto out; 570c1e26e1eSJan Glauber } 571c1e26e1eSJan Glauber 5721efbd15cSJan Glauber static void __exit des_s390_exit(void) 573c1e26e1eSJan Glauber { 5740200f3ecSGerald Schaefer if (ctrblk) { 5750200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des_alg); 5760200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des3_alg); 5770200f3ecSGerald Schaefer free_page((unsigned long) ctrblk); 5780200f3ecSGerald Schaefer } 57998971f84SJan Glauber crypto_unregister_alg(&cbc_des3_alg); 58098971f84SJan Glauber crypto_unregister_alg(&ecb_des3_alg); 58198971f84SJan Glauber crypto_unregister_alg(&des3_alg); 582a9e62fadSHerbert Xu crypto_unregister_alg(&cbc_des_alg); 583a9e62fadSHerbert Xu crypto_unregister_alg(&ecb_des_alg); 584c1e26e1eSJan Glauber crypto_unregister_alg(&des_alg); 585c1e26e1eSJan Glauber } 586c1e26e1eSJan Glauber 5879f7819c1SHeiko Carstens module_init(des_s390_init); 5881efbd15cSJan Glauber module_exit(des_s390_exit); 589c1e26e1eSJan Glauber 590c1e26e1eSJan Glauber MODULE_ALIAS("des"); 591c1e26e1eSJan Glauber MODULE_ALIAS("des3_ede"); 592c1e26e1eSJan Glauber 593c1e26e1eSJan Glauber MODULE_LICENSE("GPL"); 594c1e26e1eSJan Glauber MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); 595