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; 28ee97dc7dSHarald Freudenberger static DEFINE_SPINLOCK(ctrblk_lock); 290200f3ecSGerald Schaefer 3098971f84SJan Glauber struct s390_des_ctx { 31c1e26e1eSJan Glauber u8 iv[DES_BLOCK_SIZE]; 3298971f84SJan Glauber u8 key[DES3_KEY_SIZE]; 33c1e26e1eSJan Glauber }; 34c1e26e1eSJan Glauber 356c2bb98bSHerbert Xu static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 3698971f84SJan Glauber unsigned int key_len) 37c1e26e1eSJan Glauber { 3898971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 39560c06aeSHerbert Xu u32 *flags = &tfm->crt_flags; 401efbd15cSJan Glauber u32 tmp[DES_EXPKEY_WORDS]; 41c1e26e1eSJan Glauber 421efbd15cSJan Glauber /* check for weak keys */ 431efbd15cSJan Glauber if (!des_ekey(tmp, key) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { 441efbd15cSJan Glauber *flags |= CRYPTO_TFM_RES_WEAK_KEY; 451efbd15cSJan Glauber return -EINVAL; 461efbd15cSJan Glauber } 471efbd15cSJan Glauber 4898971f84SJan Glauber memcpy(ctx->key, key, key_len); 491efbd15cSJan Glauber return 0; 50c1e26e1eSJan Glauber } 51c1e26e1eSJan Glauber 526c2bb98bSHerbert Xu static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 53c1e26e1eSJan Glauber { 5498971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 55c1e26e1eSJan Glauber 5698971f84SJan Glauber crypt_s390_km(KM_DEA_ENCRYPT, ctx->key, out, in, DES_BLOCK_SIZE); 57c1e26e1eSJan Glauber } 58c1e26e1eSJan Glauber 596c2bb98bSHerbert Xu static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 60c1e26e1eSJan Glauber { 6198971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 62c1e26e1eSJan Glauber 6398971f84SJan Glauber crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE); 64b8dc6038SJan Glauber } 65b8dc6038SJan Glauber 66c1e26e1eSJan Glauber static struct crypto_alg des_alg = { 67c1e26e1eSJan Glauber .cra_name = "des", 6865b75c36SHerbert Xu .cra_driver_name = "des-s390", 6965b75c36SHerbert Xu .cra_priority = CRYPT_S390_PRIORITY, 70c1e26e1eSJan Glauber .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 71c1e26e1eSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 7298971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 73c1e26e1eSJan Glauber .cra_module = THIS_MODULE, 74c1357833SJan Glauber .cra_u = { 75c1357833SJan Glauber .cipher = { 76c1e26e1eSJan Glauber .cia_min_keysize = DES_KEY_SIZE, 77c1e26e1eSJan Glauber .cia_max_keysize = DES_KEY_SIZE, 78c1e26e1eSJan Glauber .cia_setkey = des_setkey, 79c1e26e1eSJan Glauber .cia_encrypt = des_encrypt, 80b8dc6038SJan Glauber .cia_decrypt = des_decrypt, 81c1357833SJan Glauber } 82c1357833SJan Glauber } 83c1e26e1eSJan Glauber }; 84c1e26e1eSJan Glauber 85a9e62fadSHerbert Xu static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, 8698971f84SJan Glauber u8 *key, struct blkcipher_walk *walk) 87a9e62fadSHerbert Xu { 88a9e62fadSHerbert Xu int ret = blkcipher_walk_virt(desc, walk); 89a9e62fadSHerbert Xu unsigned int nbytes; 90a9e62fadSHerbert Xu 91a9e62fadSHerbert Xu while ((nbytes = walk->nbytes)) { 92a9e62fadSHerbert Xu /* only use complete blocks */ 93a9e62fadSHerbert Xu unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); 94a9e62fadSHerbert Xu u8 *out = walk->dst.virt.addr; 95a9e62fadSHerbert Xu u8 *in = walk->src.virt.addr; 96a9e62fadSHerbert Xu 9798971f84SJan Glauber ret = crypt_s390_km(func, key, out, in, n); 9836eb2caaSJan Glauber if (ret < 0 || ret != n) 9936eb2caaSJan Glauber return -EIO; 100a9e62fadSHerbert Xu 101a9e62fadSHerbert Xu nbytes &= DES_BLOCK_SIZE - 1; 102a9e62fadSHerbert Xu ret = blkcipher_walk_done(desc, walk, nbytes); 103a9e62fadSHerbert Xu } 104a9e62fadSHerbert Xu 105a9e62fadSHerbert Xu return ret; 106a9e62fadSHerbert Xu } 107a9e62fadSHerbert Xu 108a9e62fadSHerbert Xu static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, 109adc3fcf1SHarald Freudenberger struct blkcipher_walk *walk) 110a9e62fadSHerbert Xu { 111adc3fcf1SHarald Freudenberger struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 112a9e62fadSHerbert Xu int ret = blkcipher_walk_virt(desc, walk); 113a9e62fadSHerbert Xu unsigned int nbytes = walk->nbytes; 114adc3fcf1SHarald Freudenberger struct { 115adc3fcf1SHarald Freudenberger u8 iv[DES_BLOCK_SIZE]; 116adc3fcf1SHarald Freudenberger u8 key[DES3_KEY_SIZE]; 117adc3fcf1SHarald Freudenberger } param; 118a9e62fadSHerbert Xu 119a9e62fadSHerbert Xu if (!nbytes) 120a9e62fadSHerbert Xu goto out; 121a9e62fadSHerbert Xu 122adc3fcf1SHarald Freudenberger memcpy(param.iv, walk->iv, DES_BLOCK_SIZE); 123adc3fcf1SHarald Freudenberger memcpy(param.key, ctx->key, DES3_KEY_SIZE); 124a9e62fadSHerbert Xu do { 125a9e62fadSHerbert Xu /* only use complete blocks */ 126a9e62fadSHerbert Xu unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); 127a9e62fadSHerbert Xu u8 *out = walk->dst.virt.addr; 128a9e62fadSHerbert Xu u8 *in = walk->src.virt.addr; 129a9e62fadSHerbert Xu 130adc3fcf1SHarald Freudenberger ret = crypt_s390_kmc(func, ¶m, out, in, n); 13136eb2caaSJan Glauber if (ret < 0 || ret != n) 13236eb2caaSJan Glauber return -EIO; 133a9e62fadSHerbert Xu 134a9e62fadSHerbert Xu nbytes &= DES_BLOCK_SIZE - 1; 135a9e62fadSHerbert Xu ret = blkcipher_walk_done(desc, walk, nbytes); 136a9e62fadSHerbert Xu } while ((nbytes = walk->nbytes)); 137adc3fcf1SHarald Freudenberger memcpy(walk->iv, param.iv, DES_BLOCK_SIZE); 138a9e62fadSHerbert Xu 139a9e62fadSHerbert Xu out: 140a9e62fadSHerbert Xu return ret; 141a9e62fadSHerbert Xu } 142a9e62fadSHerbert Xu 143a9e62fadSHerbert Xu static int ecb_des_encrypt(struct blkcipher_desc *desc, 144a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 145a9e62fadSHerbert Xu unsigned int nbytes) 146a9e62fadSHerbert Xu { 14798971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 148a9e62fadSHerbert Xu struct blkcipher_walk walk; 149a9e62fadSHerbert Xu 150a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 15198971f84SJan Glauber return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, ctx->key, &walk); 152a9e62fadSHerbert Xu } 153a9e62fadSHerbert Xu 154a9e62fadSHerbert Xu static int ecb_des_decrypt(struct blkcipher_desc *desc, 155a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 156a9e62fadSHerbert Xu unsigned int nbytes) 157a9e62fadSHerbert Xu { 15898971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 159a9e62fadSHerbert Xu struct blkcipher_walk walk; 160a9e62fadSHerbert Xu 161a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 16298971f84SJan Glauber return ecb_desall_crypt(desc, KM_DEA_DECRYPT, ctx->key, &walk); 163a9e62fadSHerbert Xu } 164a9e62fadSHerbert Xu 165a9e62fadSHerbert Xu static struct crypto_alg ecb_des_alg = { 166a9e62fadSHerbert Xu .cra_name = "ecb(des)", 167a9e62fadSHerbert Xu .cra_driver_name = "ecb-des-s390", 168a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 169a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 170a9e62fadSHerbert Xu .cra_blocksize = DES_BLOCK_SIZE, 17198971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 172a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 173a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 174a9e62fadSHerbert Xu .cra_u = { 175a9e62fadSHerbert Xu .blkcipher = { 176a9e62fadSHerbert Xu .min_keysize = DES_KEY_SIZE, 177a9e62fadSHerbert Xu .max_keysize = DES_KEY_SIZE, 178a9e62fadSHerbert Xu .setkey = des_setkey, 179a9e62fadSHerbert Xu .encrypt = ecb_des_encrypt, 180a9e62fadSHerbert Xu .decrypt = ecb_des_decrypt, 181a9e62fadSHerbert Xu } 182a9e62fadSHerbert Xu } 183a9e62fadSHerbert Xu }; 184a9e62fadSHerbert Xu 185a9e62fadSHerbert Xu static int cbc_des_encrypt(struct blkcipher_desc *desc, 186a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 187a9e62fadSHerbert Xu unsigned int nbytes) 188a9e62fadSHerbert Xu { 189a9e62fadSHerbert Xu struct blkcipher_walk walk; 190a9e62fadSHerbert Xu 191a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 192adc3fcf1SHarald Freudenberger return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk); 193a9e62fadSHerbert Xu } 194a9e62fadSHerbert Xu 195a9e62fadSHerbert Xu static int cbc_des_decrypt(struct blkcipher_desc *desc, 196a9e62fadSHerbert Xu struct scatterlist *dst, struct scatterlist *src, 197a9e62fadSHerbert Xu unsigned int nbytes) 198a9e62fadSHerbert Xu { 199a9e62fadSHerbert Xu struct blkcipher_walk walk; 200a9e62fadSHerbert Xu 201a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 202adc3fcf1SHarald Freudenberger return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk); 203a9e62fadSHerbert Xu } 204a9e62fadSHerbert Xu 205a9e62fadSHerbert Xu static struct crypto_alg cbc_des_alg = { 206a9e62fadSHerbert Xu .cra_name = "cbc(des)", 207a9e62fadSHerbert Xu .cra_driver_name = "cbc-des-s390", 208a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 209a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 210a9e62fadSHerbert Xu .cra_blocksize = DES_BLOCK_SIZE, 21198971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 212a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 213a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 214a9e62fadSHerbert Xu .cra_u = { 215a9e62fadSHerbert Xu .blkcipher = { 216a9e62fadSHerbert Xu .min_keysize = DES_KEY_SIZE, 217a9e62fadSHerbert Xu .max_keysize = DES_KEY_SIZE, 218a9e62fadSHerbert Xu .ivsize = DES_BLOCK_SIZE, 219a9e62fadSHerbert Xu .setkey = des_setkey, 220a9e62fadSHerbert Xu .encrypt = cbc_des_encrypt, 221a9e62fadSHerbert Xu .decrypt = cbc_des_decrypt, 222a9e62fadSHerbert Xu } 223a9e62fadSHerbert Xu } 224a9e62fadSHerbert Xu }; 225a9e62fadSHerbert Xu 226c1e26e1eSJan Glauber /* 227c1e26e1eSJan Glauber * RFC2451: 228c1e26e1eSJan Glauber * 229c1e26e1eSJan Glauber * For DES-EDE3, there is no known need to reject weak or 230c1e26e1eSJan Glauber * complementation keys. Any weakness is obviated by the use of 231c1e26e1eSJan Glauber * multiple keys. 232c1e26e1eSJan Glauber * 233c1e26e1eSJan Glauber * However, if the first two or last two independent 64-bit keys are 234c1e26e1eSJan Glauber * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the 235c1e26e1eSJan Glauber * same as DES. Implementers MUST reject keys that exhibit this 236c1e26e1eSJan Glauber * property. 237c1e26e1eSJan Glauber * 238c1e26e1eSJan Glauber */ 23998971f84SJan Glauber static int des3_setkey(struct crypto_tfm *tfm, const u8 *key, 24098971f84SJan Glauber unsigned int key_len) 241c1e26e1eSJan Glauber { 24298971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 243560c06aeSHerbert Xu u32 *flags = &tfm->crt_flags; 244c1e26e1eSJan Glauber 245fed28611SDaniel Borkmann if (!(crypto_memneq(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 246fed28611SDaniel Borkmann crypto_memneq(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], 24703b56ce5SJarod Wilson DES_KEY_SIZE)) && 24803b56ce5SJarod Wilson (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { 24903b56ce5SJarod Wilson *flags |= CRYPTO_TFM_RES_WEAK_KEY; 250c1e26e1eSJan Glauber return -EINVAL; 251c1e26e1eSJan Glauber } 25298971f84SJan Glauber memcpy(ctx->key, key, key_len); 253c1e26e1eSJan Glauber return 0; 254c1e26e1eSJan Glauber } 255c1e26e1eSJan Glauber 25698971f84SJan Glauber static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 257c1e26e1eSJan Glauber { 25898971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 259c1e26e1eSJan Glauber 26098971f84SJan Glauber crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); 261c1e26e1eSJan Glauber } 262c1e26e1eSJan Glauber 26398971f84SJan Glauber static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) 264c1e26e1eSJan Glauber { 26598971f84SJan Glauber struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); 266c1e26e1eSJan Glauber 26798971f84SJan Glauber crypt_s390_km(KM_TDEA_192_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); 268c1e26e1eSJan Glauber } 269c1e26e1eSJan Glauber 27098971f84SJan Glauber static struct crypto_alg des3_alg = { 271c1e26e1eSJan Glauber .cra_name = "des3_ede", 27265b75c36SHerbert Xu .cra_driver_name = "des3_ede-s390", 27365b75c36SHerbert Xu .cra_priority = CRYPT_S390_PRIORITY, 274c1e26e1eSJan Glauber .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 2751efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 27698971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 277c1e26e1eSJan Glauber .cra_module = THIS_MODULE, 278c1357833SJan Glauber .cra_u = { 279c1357833SJan Glauber .cipher = { 28098971f84SJan Glauber .cia_min_keysize = DES3_KEY_SIZE, 28198971f84SJan Glauber .cia_max_keysize = DES3_KEY_SIZE, 28298971f84SJan Glauber .cia_setkey = des3_setkey, 28398971f84SJan Glauber .cia_encrypt = des3_encrypt, 28498971f84SJan Glauber .cia_decrypt = des3_decrypt, 285c1357833SJan Glauber } 286c1357833SJan Glauber } 287c1e26e1eSJan Glauber }; 288c1e26e1eSJan Glauber 28998971f84SJan Glauber static int ecb_des3_encrypt(struct blkcipher_desc *desc, 29098971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 29198971f84SJan Glauber unsigned int nbytes) 292a9e62fadSHerbert Xu { 29398971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 294a9e62fadSHerbert Xu struct blkcipher_walk walk; 295a9e62fadSHerbert Xu 296a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 29798971f84SJan Glauber return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, ctx->key, &walk); 298a9e62fadSHerbert Xu } 299a9e62fadSHerbert Xu 30098971f84SJan Glauber static int ecb_des3_decrypt(struct blkcipher_desc *desc, 30198971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 30298971f84SJan Glauber unsigned int nbytes) 303a9e62fadSHerbert Xu { 30498971f84SJan Glauber struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 305a9e62fadSHerbert Xu struct blkcipher_walk walk; 306a9e62fadSHerbert Xu 307a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 30898971f84SJan Glauber return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, ctx->key, &walk); 309a9e62fadSHerbert Xu } 310a9e62fadSHerbert Xu 31198971f84SJan Glauber static struct crypto_alg ecb_des3_alg = { 312a9e62fadSHerbert Xu .cra_name = "ecb(des3_ede)", 313a9e62fadSHerbert Xu .cra_driver_name = "ecb-des3_ede-s390", 314a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 315a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 3161efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 31798971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 318a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 319a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 320a9e62fadSHerbert Xu .cra_u = { 321a9e62fadSHerbert Xu .blkcipher = { 32298971f84SJan Glauber .min_keysize = DES3_KEY_SIZE, 32398971f84SJan Glauber .max_keysize = DES3_KEY_SIZE, 32498971f84SJan Glauber .setkey = des3_setkey, 32598971f84SJan Glauber .encrypt = ecb_des3_encrypt, 32698971f84SJan Glauber .decrypt = ecb_des3_decrypt, 327a9e62fadSHerbert Xu } 328a9e62fadSHerbert Xu } 329a9e62fadSHerbert Xu }; 330a9e62fadSHerbert Xu 33198971f84SJan Glauber static int cbc_des3_encrypt(struct blkcipher_desc *desc, 33298971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 33398971f84SJan Glauber unsigned int nbytes) 334a9e62fadSHerbert Xu { 335a9e62fadSHerbert Xu struct blkcipher_walk walk; 336a9e62fadSHerbert Xu 337a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 338adc3fcf1SHarald Freudenberger return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk); 339a9e62fadSHerbert Xu } 340a9e62fadSHerbert Xu 34198971f84SJan Glauber static int cbc_des3_decrypt(struct blkcipher_desc *desc, 34298971f84SJan Glauber struct scatterlist *dst, struct scatterlist *src, 34398971f84SJan Glauber unsigned int nbytes) 344a9e62fadSHerbert Xu { 345a9e62fadSHerbert Xu struct blkcipher_walk walk; 346a9e62fadSHerbert Xu 347a9e62fadSHerbert Xu blkcipher_walk_init(&walk, dst, src, nbytes); 348adc3fcf1SHarald Freudenberger return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk); 349a9e62fadSHerbert Xu } 350a9e62fadSHerbert Xu 35198971f84SJan Glauber static struct crypto_alg cbc_des3_alg = { 352a9e62fadSHerbert Xu .cra_name = "cbc(des3_ede)", 353a9e62fadSHerbert Xu .cra_driver_name = "cbc-des3_ede-s390", 354a9e62fadSHerbert Xu .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 355a9e62fadSHerbert Xu .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 3561efbd15cSJan Glauber .cra_blocksize = DES_BLOCK_SIZE, 35798971f84SJan Glauber .cra_ctxsize = sizeof(struct s390_des_ctx), 358a9e62fadSHerbert Xu .cra_type = &crypto_blkcipher_type, 359a9e62fadSHerbert Xu .cra_module = THIS_MODULE, 360a9e62fadSHerbert Xu .cra_u = { 361a9e62fadSHerbert Xu .blkcipher = { 36298971f84SJan Glauber .min_keysize = DES3_KEY_SIZE, 36398971f84SJan Glauber .max_keysize = DES3_KEY_SIZE, 3641efbd15cSJan Glauber .ivsize = DES_BLOCK_SIZE, 36598971f84SJan Glauber .setkey = des3_setkey, 36698971f84SJan Glauber .encrypt = cbc_des3_encrypt, 36798971f84SJan Glauber .decrypt = cbc_des3_decrypt, 368a9e62fadSHerbert Xu } 369a9e62fadSHerbert Xu } 370a9e62fadSHerbert Xu }; 371a9e62fadSHerbert Xu 372ee97dc7dSHarald Freudenberger static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) 373ee97dc7dSHarald Freudenberger { 374ee97dc7dSHarald Freudenberger unsigned int i, n; 375ee97dc7dSHarald Freudenberger 376ee97dc7dSHarald Freudenberger /* align to block size, max. PAGE_SIZE */ 377ee97dc7dSHarald Freudenberger n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1); 378ee97dc7dSHarald Freudenberger for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { 379ee97dc7dSHarald Freudenberger memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE); 380ee97dc7dSHarald Freudenberger crypto_inc(ctrptr + i, DES_BLOCK_SIZE); 381ee97dc7dSHarald Freudenberger } 382ee97dc7dSHarald Freudenberger return n; 383ee97dc7dSHarald Freudenberger } 384ee97dc7dSHarald Freudenberger 3850200f3ecSGerald Schaefer static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, 386ee97dc7dSHarald Freudenberger struct s390_des_ctx *ctx, 387ee97dc7dSHarald Freudenberger struct blkcipher_walk *walk) 3880200f3ecSGerald Schaefer { 3890200f3ecSGerald Schaefer int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); 390ee97dc7dSHarald Freudenberger unsigned int n, nbytes; 391ee97dc7dSHarald Freudenberger u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE]; 392ee97dc7dSHarald Freudenberger u8 *out, *in, *ctrptr = ctrbuf; 3930200f3ecSGerald Schaefer 394ee97dc7dSHarald Freudenberger if (!walk->nbytes) 395ee97dc7dSHarald Freudenberger return ret; 396ee97dc7dSHarald Freudenberger 397ee97dc7dSHarald Freudenberger if (spin_trylock(&ctrblk_lock)) 398ee97dc7dSHarald Freudenberger ctrptr = ctrblk; 399ee97dc7dSHarald Freudenberger 400ee97dc7dSHarald Freudenberger memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE); 4010200f3ecSGerald Schaefer while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { 4020200f3ecSGerald Schaefer out = walk->dst.virt.addr; 4030200f3ecSGerald Schaefer in = walk->src.virt.addr; 4040200f3ecSGerald Schaefer while (nbytes >= DES_BLOCK_SIZE) { 405ee97dc7dSHarald Freudenberger if (ctrptr == ctrblk) 406ee97dc7dSHarald Freudenberger n = __ctrblk_init(ctrptr, nbytes); 407ee97dc7dSHarald Freudenberger else 408ee97dc7dSHarald Freudenberger n = DES_BLOCK_SIZE; 409ee97dc7dSHarald Freudenberger ret = crypt_s390_kmctr(func, ctx->key, out, in, 410ee97dc7dSHarald Freudenberger n, ctrptr); 411ee97dc7dSHarald Freudenberger if (ret < 0 || ret != n) { 412ee97dc7dSHarald Freudenberger if (ctrptr == ctrblk) 413ee97dc7dSHarald Freudenberger spin_unlock(&ctrblk_lock); 41436eb2caaSJan Glauber return -EIO; 415ee97dc7dSHarald Freudenberger } 4160200f3ecSGerald Schaefer if (n > DES_BLOCK_SIZE) 417ee97dc7dSHarald Freudenberger memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE, 4180200f3ecSGerald Schaefer DES_BLOCK_SIZE); 419ee97dc7dSHarald Freudenberger crypto_inc(ctrptr, DES_BLOCK_SIZE); 4200200f3ecSGerald Schaefer out += n; 4210200f3ecSGerald Schaefer in += n; 4220200f3ecSGerald Schaefer nbytes -= n; 4230200f3ecSGerald Schaefer } 4240200f3ecSGerald Schaefer ret = blkcipher_walk_done(desc, walk, nbytes); 4250200f3ecSGerald Schaefer } 426ee97dc7dSHarald Freudenberger if (ctrptr == ctrblk) { 427ee97dc7dSHarald Freudenberger if (nbytes) 428ee97dc7dSHarald Freudenberger memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE); 429ee97dc7dSHarald Freudenberger else 430ee97dc7dSHarald Freudenberger memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); 431ee97dc7dSHarald Freudenberger spin_unlock(&ctrblk_lock); 4323901c112SHarald Freudenberger } else { 4333901c112SHarald Freudenberger if (!nbytes) 4343901c112SHarald Freudenberger memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); 435ee97dc7dSHarald Freudenberger } 4360200f3ecSGerald Schaefer /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ 4370200f3ecSGerald Schaefer if (nbytes) { 4380200f3ecSGerald Schaefer out = walk->dst.virt.addr; 4390200f3ecSGerald Schaefer in = walk->src.virt.addr; 4400200f3ecSGerald Schaefer ret = crypt_s390_kmctr(func, ctx->key, buf, in, 441ee97dc7dSHarald Freudenberger DES_BLOCK_SIZE, ctrbuf); 44236eb2caaSJan Glauber if (ret < 0 || ret != DES_BLOCK_SIZE) 44336eb2caaSJan Glauber return -EIO; 4440200f3ecSGerald Schaefer memcpy(out, buf, nbytes); 445ee97dc7dSHarald Freudenberger crypto_inc(ctrbuf, DES_BLOCK_SIZE); 4460200f3ecSGerald Schaefer ret = blkcipher_walk_done(desc, walk, 0); 447ee97dc7dSHarald Freudenberger memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE); 4480200f3ecSGerald Schaefer } 4490200f3ecSGerald Schaefer return ret; 4500200f3ecSGerald Schaefer } 4510200f3ecSGerald Schaefer 4520200f3ecSGerald Schaefer static int ctr_des_encrypt(struct blkcipher_desc *desc, 4530200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4540200f3ecSGerald Schaefer unsigned int nbytes) 4550200f3ecSGerald Schaefer { 4560200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 4570200f3ecSGerald Schaefer struct blkcipher_walk walk; 4580200f3ecSGerald Schaefer 4590200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 4600200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_DEA_ENCRYPT, ctx, &walk); 4610200f3ecSGerald Schaefer } 4620200f3ecSGerald Schaefer 4630200f3ecSGerald Schaefer static int ctr_des_decrypt(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_DEA_DECRYPT, ctx, &walk); 4720200f3ecSGerald Schaefer } 4730200f3ecSGerald Schaefer 4740200f3ecSGerald Schaefer static struct crypto_alg ctr_des_alg = { 4750200f3ecSGerald Schaefer .cra_name = "ctr(des)", 4760200f3ecSGerald Schaefer .cra_driver_name = "ctr-des-s390", 4770200f3ecSGerald Schaefer .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 4780200f3ecSGerald Schaefer .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 4790200f3ecSGerald Schaefer .cra_blocksize = 1, 4800200f3ecSGerald Schaefer .cra_ctxsize = sizeof(struct s390_des_ctx), 4810200f3ecSGerald Schaefer .cra_type = &crypto_blkcipher_type, 4820200f3ecSGerald Schaefer .cra_module = THIS_MODULE, 4830200f3ecSGerald Schaefer .cra_u = { 4840200f3ecSGerald Schaefer .blkcipher = { 4850200f3ecSGerald Schaefer .min_keysize = DES_KEY_SIZE, 4860200f3ecSGerald Schaefer .max_keysize = DES_KEY_SIZE, 4870200f3ecSGerald Schaefer .ivsize = DES_BLOCK_SIZE, 4880200f3ecSGerald Schaefer .setkey = des_setkey, 4890200f3ecSGerald Schaefer .encrypt = ctr_des_encrypt, 4900200f3ecSGerald Schaefer .decrypt = ctr_des_decrypt, 4910200f3ecSGerald Schaefer } 4920200f3ecSGerald Schaefer } 4930200f3ecSGerald Schaefer }; 4940200f3ecSGerald Schaefer 4950200f3ecSGerald Schaefer static int ctr_des3_encrypt(struct blkcipher_desc *desc, 4960200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 4970200f3ecSGerald Schaefer unsigned int nbytes) 4980200f3ecSGerald Schaefer { 4990200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 5000200f3ecSGerald Schaefer struct blkcipher_walk walk; 5010200f3ecSGerald Schaefer 5020200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 5030200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_TDEA_192_ENCRYPT, ctx, &walk); 5040200f3ecSGerald Schaefer } 5050200f3ecSGerald Schaefer 5060200f3ecSGerald Schaefer static int ctr_des3_decrypt(struct blkcipher_desc *desc, 5070200f3ecSGerald Schaefer struct scatterlist *dst, struct scatterlist *src, 5080200f3ecSGerald Schaefer unsigned int nbytes) 5090200f3ecSGerald Schaefer { 5100200f3ecSGerald Schaefer struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 5110200f3ecSGerald Schaefer struct blkcipher_walk walk; 5120200f3ecSGerald Schaefer 5130200f3ecSGerald Schaefer blkcipher_walk_init(&walk, dst, src, nbytes); 5140200f3ecSGerald Schaefer return ctr_desall_crypt(desc, KMCTR_TDEA_192_DECRYPT, ctx, &walk); 5150200f3ecSGerald Schaefer } 5160200f3ecSGerald Schaefer 5170200f3ecSGerald Schaefer static struct crypto_alg ctr_des3_alg = { 5180200f3ecSGerald Schaefer .cra_name = "ctr(des3_ede)", 5190200f3ecSGerald Schaefer .cra_driver_name = "ctr-des3_ede-s390", 5200200f3ecSGerald Schaefer .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, 5210200f3ecSGerald Schaefer .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, 5220200f3ecSGerald Schaefer .cra_blocksize = 1, 5230200f3ecSGerald Schaefer .cra_ctxsize = sizeof(struct s390_des_ctx), 5240200f3ecSGerald Schaefer .cra_type = &crypto_blkcipher_type, 5250200f3ecSGerald Schaefer .cra_module = THIS_MODULE, 5260200f3ecSGerald Schaefer .cra_u = { 5270200f3ecSGerald Schaefer .blkcipher = { 5280200f3ecSGerald Schaefer .min_keysize = DES3_KEY_SIZE, 5290200f3ecSGerald Schaefer .max_keysize = DES3_KEY_SIZE, 5300200f3ecSGerald Schaefer .ivsize = DES_BLOCK_SIZE, 5310200f3ecSGerald Schaefer .setkey = des3_setkey, 5320200f3ecSGerald Schaefer .encrypt = ctr_des3_encrypt, 5330200f3ecSGerald Schaefer .decrypt = ctr_des3_decrypt, 5340200f3ecSGerald Schaefer } 5350200f3ecSGerald Schaefer } 5360200f3ecSGerald Schaefer }; 5370200f3ecSGerald Schaefer 53898971f84SJan Glauber static int __init des_s390_init(void) 539c1e26e1eSJan Glauber { 54080d663a4SJan Glauber int ret; 541c1e26e1eSJan Glauber 5421822bc90SJan Glauber if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) || 5431822bc90SJan Glauber !crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA)) 54486aa9fc2SJan Glauber return -EOPNOTSUPP; 545c1e26e1eSJan Glauber 546a9e62fadSHerbert Xu ret = crypto_register_alg(&des_alg); 547a9e62fadSHerbert Xu if (ret) 548a9e62fadSHerbert Xu goto des_err; 549a9e62fadSHerbert Xu ret = crypto_register_alg(&ecb_des_alg); 550a9e62fadSHerbert Xu if (ret) 551a9e62fadSHerbert Xu goto ecb_des_err; 552a9e62fadSHerbert Xu ret = crypto_register_alg(&cbc_des_alg); 553a9e62fadSHerbert Xu if (ret) 554a9e62fadSHerbert Xu goto cbc_des_err; 55598971f84SJan Glauber ret = crypto_register_alg(&des3_alg); 556a9e62fadSHerbert Xu if (ret) 55798971f84SJan Glauber goto des3_err; 55898971f84SJan Glauber ret = crypto_register_alg(&ecb_des3_alg); 559a9e62fadSHerbert Xu if (ret) 56098971f84SJan Glauber goto ecb_des3_err; 56198971f84SJan Glauber ret = crypto_register_alg(&cbc_des3_alg); 562a9e62fadSHerbert Xu if (ret) 56398971f84SJan Glauber goto cbc_des3_err; 5640200f3ecSGerald Schaefer 5650200f3ecSGerald Schaefer if (crypt_s390_func_available(KMCTR_DEA_ENCRYPT, 5660200f3ecSGerald Schaefer CRYPT_S390_MSA | CRYPT_S390_MSA4) && 5670200f3ecSGerald Schaefer crypt_s390_func_available(KMCTR_TDEA_192_ENCRYPT, 5680200f3ecSGerald Schaefer CRYPT_S390_MSA | CRYPT_S390_MSA4)) { 5690200f3ecSGerald Schaefer ret = crypto_register_alg(&ctr_des_alg); 5700200f3ecSGerald Schaefer if (ret) 5710200f3ecSGerald Schaefer goto ctr_des_err; 5720200f3ecSGerald Schaefer ret = crypto_register_alg(&ctr_des3_alg); 5730200f3ecSGerald Schaefer if (ret) 5740200f3ecSGerald Schaefer goto ctr_des3_err; 5750200f3ecSGerald Schaefer ctrblk = (u8 *) __get_free_page(GFP_KERNEL); 5760200f3ecSGerald Schaefer if (!ctrblk) { 5770200f3ecSGerald Schaefer ret = -ENOMEM; 5780200f3ecSGerald Schaefer goto ctr_mem_err; 5790200f3ecSGerald Schaefer } 5800200f3ecSGerald Schaefer } 581a9e62fadSHerbert Xu out: 582a9e62fadSHerbert Xu return ret; 583a9e62fadSHerbert Xu 5840200f3ecSGerald Schaefer ctr_mem_err: 5850200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des3_alg); 5860200f3ecSGerald Schaefer ctr_des3_err: 5870200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des_alg); 5880200f3ecSGerald Schaefer ctr_des_err: 5890200f3ecSGerald Schaefer crypto_unregister_alg(&cbc_des3_alg); 59098971f84SJan Glauber cbc_des3_err: 59198971f84SJan Glauber crypto_unregister_alg(&ecb_des3_alg); 59298971f84SJan Glauber ecb_des3_err: 59398971f84SJan Glauber crypto_unregister_alg(&des3_alg); 59498971f84SJan Glauber des3_err: 595a9e62fadSHerbert Xu crypto_unregister_alg(&cbc_des_alg); 596a9e62fadSHerbert Xu cbc_des_err: 597a9e62fadSHerbert Xu crypto_unregister_alg(&ecb_des_alg); 598a9e62fadSHerbert Xu ecb_des_err: 599c1e26e1eSJan Glauber crypto_unregister_alg(&des_alg); 600a9e62fadSHerbert Xu des_err: 601a9e62fadSHerbert Xu goto out; 602c1e26e1eSJan Glauber } 603c1e26e1eSJan Glauber 6041efbd15cSJan Glauber static void __exit des_s390_exit(void) 605c1e26e1eSJan Glauber { 6060200f3ecSGerald Schaefer if (ctrblk) { 6070200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des_alg); 6080200f3ecSGerald Schaefer crypto_unregister_alg(&ctr_des3_alg); 6090200f3ecSGerald Schaefer free_page((unsigned long) ctrblk); 6100200f3ecSGerald Schaefer } 61198971f84SJan Glauber crypto_unregister_alg(&cbc_des3_alg); 61298971f84SJan Glauber crypto_unregister_alg(&ecb_des3_alg); 61398971f84SJan Glauber crypto_unregister_alg(&des3_alg); 614a9e62fadSHerbert Xu crypto_unregister_alg(&cbc_des_alg); 615a9e62fadSHerbert Xu crypto_unregister_alg(&ecb_des_alg); 616c1e26e1eSJan Glauber crypto_unregister_alg(&des_alg); 617c1e26e1eSJan Glauber } 618c1e26e1eSJan Glauber 6199f7819c1SHeiko Carstens module_init(des_s390_init); 6201efbd15cSJan Glauber module_exit(des_s390_exit); 621c1e26e1eSJan Glauber 6225d26a105SKees Cook MODULE_ALIAS_CRYPTO("des"); 6235d26a105SKees Cook MODULE_ALIAS_CRYPTO("des3_ede"); 624c1e26e1eSJan Glauber 625c1e26e1eSJan Glauber MODULE_LICENSE("GPL"); 626c1e26e1eSJan Glauber MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); 627