1 /* 2 * Cryptographic API. 3 * 4 * s390 implementation of the AES Cipher Algorithm. 5 * 6 * s390 Version: 7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation 8 * Author(s): Jan Glauber (jang@de.ibm.com) 9 * 10 * Derived from "crypto/aes.c" 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the Free 14 * Software Foundation; either version 2 of the License, or (at your option) 15 * any later version. 16 * 17 */ 18 19 #include <linux/module.h> 20 #include <linux/init.h> 21 #include <linux/crypto.h> 22 #include "crypt_s390.h" 23 24 #define AES_MIN_KEY_SIZE 16 25 #define AES_MAX_KEY_SIZE 32 26 27 /* data block size for all key lengths */ 28 #define AES_BLOCK_SIZE 16 29 30 int has_aes_128 = 0; 31 int has_aes_192 = 0; 32 int has_aes_256 = 0; 33 34 struct s390_aes_ctx { 35 u8 iv[AES_BLOCK_SIZE]; 36 u8 key[AES_MAX_KEY_SIZE]; 37 int key_len; 38 }; 39 40 static int aes_set_key(void *ctx, const u8 *in_key, unsigned int key_len, 41 u32 *flags) 42 { 43 struct s390_aes_ctx *sctx = ctx; 44 45 switch (key_len) { 46 case 16: 47 if (!has_aes_128) 48 goto fail; 49 break; 50 case 24: 51 if (!has_aes_192) 52 goto fail; 53 54 break; 55 case 32: 56 if (!has_aes_256) 57 goto fail; 58 break; 59 default: 60 /* invalid key length */ 61 goto fail; 62 break; 63 } 64 65 sctx->key_len = key_len; 66 memcpy(sctx->key, in_key, key_len); 67 return 0; 68 fail: 69 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 70 return -EINVAL; 71 } 72 73 static void aes_encrypt(void *ctx, u8 *out, const u8 *in) 74 { 75 const struct s390_aes_ctx *sctx = ctx; 76 77 switch (sctx->key_len) { 78 case 16: 79 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, 80 AES_BLOCK_SIZE); 81 break; 82 case 24: 83 crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, 84 AES_BLOCK_SIZE); 85 break; 86 case 32: 87 crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, 88 AES_BLOCK_SIZE); 89 break; 90 } 91 } 92 93 static void aes_decrypt(void *ctx, u8 *out, const u8 *in) 94 { 95 const struct s390_aes_ctx *sctx = ctx; 96 97 switch (sctx->key_len) { 98 case 16: 99 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, 100 AES_BLOCK_SIZE); 101 break; 102 case 24: 103 crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, 104 AES_BLOCK_SIZE); 105 break; 106 case 32: 107 crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, 108 AES_BLOCK_SIZE); 109 break; 110 } 111 } 112 113 static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, 114 const u8 *in, unsigned int nbytes) 115 { 116 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 117 int ret; 118 119 /* only use complete blocks */ 120 nbytes &= ~(AES_BLOCK_SIZE - 1); 121 122 switch (sctx->key_len) { 123 case 16: 124 ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); 125 BUG_ON((ret < 0) || (ret != nbytes)); 126 break; 127 case 24: 128 ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); 129 BUG_ON((ret < 0) || (ret != nbytes)); 130 break; 131 case 32: 132 ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); 133 BUG_ON((ret < 0) || (ret != nbytes)); 134 break; 135 } 136 return nbytes; 137 } 138 139 static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 140 const u8 *in, unsigned int nbytes) 141 { 142 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 143 int ret; 144 145 /* only use complete blocks */ 146 nbytes &= ~(AES_BLOCK_SIZE - 1); 147 148 switch (sctx->key_len) { 149 case 16: 150 ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); 151 BUG_ON((ret < 0) || (ret != nbytes)); 152 break; 153 case 24: 154 ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes); 155 BUG_ON((ret < 0) || (ret != nbytes)); 156 break; 157 case 32: 158 ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes); 159 BUG_ON((ret < 0) || (ret != nbytes)); 160 break; 161 } 162 return nbytes; 163 } 164 165 static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 166 const u8 *in, unsigned int nbytes) 167 { 168 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 169 int ret; 170 171 /* only use complete blocks */ 172 nbytes &= ~(AES_BLOCK_SIZE - 1); 173 174 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 175 switch (sctx->key_len) { 176 case 16: 177 ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); 178 BUG_ON((ret < 0) || (ret != nbytes)); 179 break; 180 case 24: 181 ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); 182 BUG_ON((ret < 0) || (ret != nbytes)); 183 break; 184 case 32: 185 ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); 186 BUG_ON((ret < 0) || (ret != nbytes)); 187 break; 188 } 189 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE); 190 191 return nbytes; 192 } 193 194 static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 195 const u8 *in, unsigned int nbytes) 196 { 197 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 198 int ret; 199 200 /* only use complete blocks */ 201 nbytes &= ~(AES_BLOCK_SIZE - 1); 202 203 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 204 switch (sctx->key_len) { 205 case 16: 206 ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); 207 BUG_ON((ret < 0) || (ret != nbytes)); 208 break; 209 case 24: 210 ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); 211 BUG_ON((ret < 0) || (ret != nbytes)); 212 break; 213 case 32: 214 ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); 215 BUG_ON((ret < 0) || (ret != nbytes)); 216 break; 217 } 218 return nbytes; 219 } 220 221 222 static struct crypto_alg aes_alg = { 223 .cra_name = "aes", 224 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 225 .cra_blocksize = AES_BLOCK_SIZE, 226 .cra_ctxsize = sizeof(struct s390_aes_ctx), 227 .cra_module = THIS_MODULE, 228 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 229 .cra_u = { 230 .cipher = { 231 .cia_min_keysize = AES_MIN_KEY_SIZE, 232 .cia_max_keysize = AES_MAX_KEY_SIZE, 233 .cia_setkey = aes_set_key, 234 .cia_encrypt = aes_encrypt, 235 .cia_decrypt = aes_decrypt, 236 .cia_encrypt_ecb = aes_encrypt_ecb, 237 .cia_decrypt_ecb = aes_decrypt_ecb, 238 .cia_encrypt_cbc = aes_encrypt_cbc, 239 .cia_decrypt_cbc = aes_decrypt_cbc, 240 } 241 } 242 }; 243 244 static int __init aes_init(void) 245 { 246 int ret; 247 248 if (crypt_s390_func_available(KM_AES_128_ENCRYPT)) 249 has_aes_128 = 1; 250 if (crypt_s390_func_available(KM_AES_192_ENCRYPT)) 251 has_aes_192 = 1; 252 if (crypt_s390_func_available(KM_AES_256_ENCRYPT)) 253 has_aes_256 = 1; 254 255 if (!has_aes_128 && !has_aes_192 && !has_aes_256) 256 return -ENOSYS; 257 258 ret = crypto_register_alg(&aes_alg); 259 if (ret != 0) 260 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n"); 261 return ret; 262 } 263 264 static void __exit aes_fini(void) 265 { 266 crypto_unregister_alg(&aes_alg); 267 } 268 269 module_init(aes_init); 270 module_exit(aes_fini); 271 272 MODULE_ALIAS("aes"); 273 274 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); 275 MODULE_LICENSE("GPL"); 276 277