1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* Glue code for DES encryption optimized for 3 * 4 * Copyright (C) 2012 David S. Miller <davem@d 5 */ 6 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fm 8 9 #include <linux/crypto.h> 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/mm.h> 13 #include <linux/types.h> 14 #include <crypto/algapi.h> 15 #include <crypto/internal/des.h> 16 #include <crypto/internal/skcipher.h> 17 18 #include <asm/fpumacro.h> 19 #include <asm/pstate.h> 20 #include <asm/elf.h> 21 22 #include "opcodes.h" 23 24 struct des_sparc64_ctx { 25 u64 encrypt_expkey[DES_EXPKEY_WORDS / 26 u64 decrypt_expkey[DES_EXPKEY_WORDS / 27 }; 28 29 struct des3_ede_sparc64_ctx { 30 u64 encrypt_expkey[DES3_EDE_EXPKEY_WOR 31 u64 decrypt_expkey[DES3_EDE_EXPKEY_WOR 32 }; 33 34 static void encrypt_to_decrypt(u64 *d, const u 35 { 36 const u64 *s = e + (DES_EXPKEY_WORDS / 37 int i; 38 39 for (i = 0; i < DES_EXPKEY_WORDS / 2; 40 *d++ = *s--; 41 } 42 43 extern void des_sparc64_key_expand(const u32 * 44 45 static int des_set_key(struct crypto_tfm *tfm, 46 unsigned int keylen) 47 { 48 struct des_sparc64_ctx *dctx = crypto_ 49 int err; 50 51 /* Even though we have special instruc 52 * we call des_verify_key() so that we 53 * weak key detection code. 54 */ 55 err = crypto_des_verify_key(tfm, key); 56 if (err) 57 return err; 58 59 des_sparc64_key_expand((const u32 *) k 60 encrypt_to_decrypt(&dctx->decrypt_expk 61 62 return 0; 63 } 64 65 static int des_set_key_skcipher(struct crypto_ 66 unsigned int k 67 { 68 return des_set_key(crypto_skcipher_tfm 69 } 70 71 extern void des_sparc64_crypt(const u64 *key, 72 u64 *output); 73 74 static void sparc_des_encrypt(struct crypto_tf 75 { 76 struct des_sparc64_ctx *ctx = crypto_t 77 const u64 *K = ctx->encrypt_expkey; 78 79 des_sparc64_crypt(K, (const u64 *) src 80 } 81 82 static void sparc_des_decrypt(struct crypto_tf 83 { 84 struct des_sparc64_ctx *ctx = crypto_t 85 const u64 *K = ctx->decrypt_expkey; 86 87 des_sparc64_crypt(K, (const u64 *) src 88 } 89 90 extern void des_sparc64_load_keys(const u64 *k 91 92 extern void des_sparc64_ecb_crypt(const u64 *i 93 unsigned int 94 95 static int __ecb_crypt(struct skcipher_request 96 { 97 struct crypto_skcipher *tfm = crypto_s 98 const struct des_sparc64_ctx *ctx = cr 99 struct skcipher_walk walk; 100 unsigned int nbytes; 101 int err; 102 103 err = skcipher_walk_virt(&walk, req, t 104 if (err) 105 return err; 106 107 if (encrypt) 108 des_sparc64_load_keys(&ctx->en 109 else 110 des_sparc64_load_keys(&ctx->de 111 while ((nbytes = walk.nbytes) != 0) { 112 des_sparc64_ecb_crypt(walk.src 113 round_do 114 err = skcipher_walk_done(&walk 115 } 116 fprs_write(0); 117 return err; 118 } 119 120 static int ecb_encrypt(struct skcipher_request 121 { 122 return __ecb_crypt(req, true); 123 } 124 125 static int ecb_decrypt(struct skcipher_request 126 { 127 return __ecb_crypt(req, false); 128 } 129 130 extern void des_sparc64_cbc_encrypt(const u64 131 unsigned i 132 133 extern void des_sparc64_cbc_decrypt(const u64 134 unsigned i 135 136 static int __cbc_crypt(struct skcipher_request 137 { 138 struct crypto_skcipher *tfm = crypto_s 139 const struct des_sparc64_ctx *ctx = cr 140 struct skcipher_walk walk; 141 unsigned int nbytes; 142 int err; 143 144 err = skcipher_walk_virt(&walk, req, t 145 if (err) 146 return err; 147 148 if (encrypt) 149 des_sparc64_load_keys(&ctx->en 150 else 151 des_sparc64_load_keys(&ctx->de 152 while ((nbytes = walk.nbytes) != 0) { 153 if (encrypt) 154 des_sparc64_cbc_encryp 155 156 157 158 159 else 160 des_sparc64_cbc_decryp 161 162 163 164 165 err = skcipher_walk_done(&walk 166 } 167 fprs_write(0); 168 return err; 169 } 170 171 static int cbc_encrypt(struct skcipher_request 172 { 173 return __cbc_crypt(req, true); 174 } 175 176 static int cbc_decrypt(struct skcipher_request 177 { 178 return __cbc_crypt(req, false); 179 } 180 181 static int des3_ede_set_key(struct crypto_tfm 182 unsigned int keyle 183 { 184 struct des3_ede_sparc64_ctx *dctx = cr 185 u64 k1[DES_EXPKEY_WORDS / 2]; 186 u64 k2[DES_EXPKEY_WORDS / 2]; 187 u64 k3[DES_EXPKEY_WORDS / 2]; 188 int err; 189 190 err = crypto_des3_ede_verify_key(tfm, 191 if (err) 192 return err; 193 194 des_sparc64_key_expand((const u32 *)ke 195 key += DES_KEY_SIZE; 196 des_sparc64_key_expand((const u32 *)ke 197 key += DES_KEY_SIZE; 198 des_sparc64_key_expand((const u32 *)ke 199 200 memcpy(&dctx->encrypt_expkey[0], &k1[0 201 encrypt_to_decrypt(&dctx->encrypt_expk 202 memcpy(&dctx->encrypt_expkey[(DES_EXPK 203 &k3[0], sizeof(k3)); 204 205 encrypt_to_decrypt(&dctx->decrypt_expk 206 memcpy(&dctx->decrypt_expkey[DES_EXPKE 207 &k2[0], sizeof(k2)); 208 encrypt_to_decrypt(&dctx->decrypt_expk 209 &k1[0]); 210 211 return 0; 212 } 213 214 static int des3_ede_set_key_skcipher(struct cr 215 unsigned 216 { 217 return des3_ede_set_key(crypto_skciphe 218 } 219 220 extern void des3_ede_sparc64_crypt(const u64 * 221 u64 *output 222 223 static void sparc_des3_ede_encrypt(struct cryp 224 { 225 struct des3_ede_sparc64_ctx *ctx = cry 226 const u64 *K = ctx->encrypt_expkey; 227 228 des3_ede_sparc64_crypt(K, (const u64 * 229 } 230 231 static void sparc_des3_ede_decrypt(struct cryp 232 { 233 struct des3_ede_sparc64_ctx *ctx = cry 234 const u64 *K = ctx->decrypt_expkey; 235 236 des3_ede_sparc64_crypt(K, (const u64 * 237 } 238 239 extern void des3_ede_sparc64_load_keys(const u 240 241 extern void des3_ede_sparc64_ecb_crypt(const u 242 u64 *ou 243 244 static int __ecb3_crypt(struct skcipher_reques 245 { 246 struct crypto_skcipher *tfm = crypto_s 247 const struct des3_ede_sparc64_ctx *ctx 248 struct skcipher_walk walk; 249 const u64 *K; 250 unsigned int nbytes; 251 int err; 252 253 err = skcipher_walk_virt(&walk, req, t 254 if (err) 255 return err; 256 257 if (encrypt) 258 K = &ctx->encrypt_expkey[0]; 259 else 260 K = &ctx->decrypt_expkey[0]; 261 des3_ede_sparc64_load_keys(K); 262 while ((nbytes = walk.nbytes) != 0) { 263 des3_ede_sparc64_ecb_crypt(K, 264 wal 265 rou 266 err = skcipher_walk_done(&walk 267 } 268 fprs_write(0); 269 return err; 270 } 271 272 static int ecb3_encrypt(struct skcipher_reques 273 { 274 return __ecb3_crypt(req, true); 275 } 276 277 static int ecb3_decrypt(struct skcipher_reques 278 { 279 return __ecb3_crypt(req, false); 280 } 281 282 extern void des3_ede_sparc64_cbc_encrypt(const 283 u64 * 284 u64 * 285 286 extern void des3_ede_sparc64_cbc_decrypt(const 287 u64 * 288 u64 * 289 290 static int __cbc3_crypt(struct skcipher_reques 291 { 292 struct crypto_skcipher *tfm = crypto_s 293 const struct des3_ede_sparc64_ctx *ctx 294 struct skcipher_walk walk; 295 const u64 *K; 296 unsigned int nbytes; 297 int err; 298 299 err = skcipher_walk_virt(&walk, req, t 300 if (err) 301 return err; 302 303 if (encrypt) 304 K = &ctx->encrypt_expkey[0]; 305 else 306 K = &ctx->decrypt_expkey[0]; 307 des3_ede_sparc64_load_keys(K); 308 while ((nbytes = walk.nbytes) != 0) { 309 if (encrypt) 310 des3_ede_sparc64_cbc_e 311 312 313 314 315 else 316 des3_ede_sparc64_cbc_d 317 318 319 320 321 err = skcipher_walk_done(&walk 322 } 323 fprs_write(0); 324 return err; 325 } 326 327 static int cbc3_encrypt(struct skcipher_reques 328 { 329 return __cbc3_crypt(req, true); 330 } 331 332 static int cbc3_decrypt(struct skcipher_reques 333 { 334 return __cbc3_crypt(req, false); 335 } 336 337 static struct crypto_alg cipher_algs[] = { 338 { 339 .cra_name = "des 340 .cra_driver_name = "des 341 .cra_priority = SPAR 342 .cra_flags = CRYP 343 .cra_blocksize = DES_ 344 .cra_ctxsize = size 345 .cra_alignmask = 7, 346 .cra_module = THIS 347 .cra_u = { 348 .cipher = { 349 .cia_min_keysi 350 .cia_max_keysi 351 .cia_setkey 352 .cia_encrypt 353 .cia_decrypt 354 } 355 } 356 }, { 357 .cra_name = "des 358 .cra_driver_name = "des 359 .cra_priority = SPAR 360 .cra_flags = CRYP 361 .cra_blocksize = DES3 362 .cra_ctxsize = size 363 .cra_alignmask = 7, 364 .cra_module = THIS 365 .cra_u = { 366 .cipher = { 367 .cia_min_keysi 368 .cia_max_keysi 369 .cia_setkey 370 .cia_encrypt 371 .cia_decrypt 372 } 373 } 374 } 375 }; 376 377 static struct skcipher_alg skcipher_algs[] = { 378 { 379 .base.cra_name = "ecb 380 .base.cra_driver_name = "ecb 381 .base.cra_priority = SPAR 382 .base.cra_blocksize = DES_ 383 .base.cra_ctxsize = size 384 .base.cra_alignmask = 7, 385 .base.cra_module = THIS 386 .min_keysize = DES_ 387 .max_keysize = DES_ 388 .setkey = des_ 389 .encrypt = ecb_ 390 .decrypt = ecb_ 391 }, { 392 .base.cra_name = "cbc 393 .base.cra_driver_name = "cbc 394 .base.cra_priority = SPAR 395 .base.cra_blocksize = DES_ 396 .base.cra_ctxsize = size 397 .base.cra_alignmask = 7, 398 .base.cra_module = THIS 399 .min_keysize = DES_ 400 .max_keysize = DES_ 401 .ivsize = DES_ 402 .setkey = des_ 403 .encrypt = cbc_ 404 .decrypt = cbc_ 405 }, { 406 .base.cra_name = "ecb 407 .base.cra_driver_name = "ecb 408 .base.cra_priority = SPAR 409 .base.cra_blocksize = DES3 410 .base.cra_ctxsize = size 411 .base.cra_alignmask = 7, 412 .base.cra_module = THIS 413 .min_keysize = DES3 414 .max_keysize = DES3 415 .setkey = des3 416 .encrypt = ecb3 417 .decrypt = ecb3 418 }, { 419 .base.cra_name = "cbc 420 .base.cra_driver_name = "cbc 421 .base.cra_priority = SPAR 422 .base.cra_blocksize = DES3 423 .base.cra_ctxsize = size 424 .base.cra_alignmask = 7, 425 .base.cra_module = THIS 426 .min_keysize = DES3 427 .max_keysize = DES3 428 .ivsize = DES3 429 .setkey = des3 430 .encrypt = cbc3 431 .decrypt = cbc3 432 } 433 }; 434 435 static bool __init sparc64_has_des_opcode(void 436 { 437 unsigned long cfr; 438 439 if (!(sparc64_elf_hwcap & HWCAP_SPARC_ 440 return false; 441 442 __asm__ __volatile__("rd %%asr26, %0" 443 if (!(cfr & CFR_DES)) 444 return false; 445 446 return true; 447 } 448 449 static int __init des_sparc64_mod_init(void) 450 { 451 int err; 452 453 if (!sparc64_has_des_opcode()) { 454 pr_info("sparc64 des opcodes n 455 return -ENODEV; 456 } 457 pr_info("Using sparc64 des opcodes opt 458 err = crypto_register_algs(cipher_algs 459 if (err) 460 return err; 461 err = crypto_register_skciphers(skciph 462 ARRAY_ 463 if (err) 464 crypto_unregister_algs(cipher_ 465 return err; 466 } 467 468 static void __exit des_sparc64_mod_fini(void) 469 { 470 crypto_unregister_algs(cipher_algs, AR 471 crypto_unregister_skciphers(skcipher_a 472 } 473 474 module_init(des_sparc64_mod_init); 475 module_exit(des_sparc64_mod_fini); 476 477 MODULE_LICENSE("GPL"); 478 MODULE_DESCRIPTION("DES & Triple DES EDE Ciphe 479 480 MODULE_ALIAS_CRYPTO("des"); 481 MODULE_ALIAS_CRYPTO("des3_ede"); 482 483 #include "crop_devid.c" 484
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.