Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19 124 lines 3.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Glue Code for SSE2 assembler versions of Serpent Cipher 4 * 5 * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 6 * 7 * Glue code based on aesni-intel_glue.c by: 8 * Copyright (C) 2008, Intel Corp. 9 * Author: Huang Ying <ying.huang@intel.com> 10 * 11 * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: 12 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 13 */ 14 15#include <linux/module.h> 16#include <linux/types.h> 17#include <linux/crypto.h> 18#include <linux/err.h> 19#include <crypto/algapi.h> 20#include <crypto/b128ops.h> 21#include <crypto/serpent.h> 22 23#include "serpent-sse2.h" 24#include "ecb_cbc_helpers.h" 25 26static int serpent_setkey_skcipher(struct crypto_skcipher *tfm, 27 const u8 *key, unsigned int keylen) 28{ 29 return __serpent_setkey(crypto_skcipher_ctx(tfm), key, keylen); 30} 31 32static void serpent_decrypt_cbc_xway(const void *ctx, u8 *dst, const u8 *src) 33{ 34 u8 buf[SERPENT_PARALLEL_BLOCKS - 1][SERPENT_BLOCK_SIZE]; 35 const u8 *s = src; 36 37 if (dst == src) 38 s = memcpy(buf, src, sizeof(buf)); 39 serpent_dec_blk_xway(ctx, dst, src); 40 crypto_xor(dst + SERPENT_BLOCK_SIZE, s, sizeof(buf)); 41} 42 43static int ecb_encrypt(struct skcipher_request *req) 44{ 45 ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS); 46 ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_enc_blk_xway); 47 ECB_BLOCK(1, __serpent_encrypt); 48 ECB_WALK_END(); 49} 50 51static int ecb_decrypt(struct skcipher_request *req) 52{ 53 ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS); 54 ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_dec_blk_xway); 55 ECB_BLOCK(1, __serpent_decrypt); 56 ECB_WALK_END(); 57} 58 59static int cbc_encrypt(struct skcipher_request *req) 60{ 61 CBC_WALK_START(req, SERPENT_BLOCK_SIZE, -1); 62 CBC_ENC_BLOCK(__serpent_encrypt); 63 CBC_WALK_END(); 64} 65 66static int cbc_decrypt(struct skcipher_request *req) 67{ 68 CBC_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS); 69 CBC_DEC_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_decrypt_cbc_xway); 70 CBC_DEC_BLOCK(1, __serpent_decrypt); 71 CBC_WALK_END(); 72} 73 74static struct skcipher_alg serpent_algs[] = { 75 { 76 .base.cra_name = "ecb(serpent)", 77 .base.cra_driver_name = "ecb-serpent-sse2", 78 .base.cra_priority = 400, 79 .base.cra_blocksize = SERPENT_BLOCK_SIZE, 80 .base.cra_ctxsize = sizeof(struct serpent_ctx), 81 .base.cra_module = THIS_MODULE, 82 .min_keysize = SERPENT_MIN_KEY_SIZE, 83 .max_keysize = SERPENT_MAX_KEY_SIZE, 84 .setkey = serpent_setkey_skcipher, 85 .encrypt = ecb_encrypt, 86 .decrypt = ecb_decrypt, 87 }, { 88 .base.cra_name = "cbc(serpent)", 89 .base.cra_driver_name = "cbc-serpent-sse2", 90 .base.cra_priority = 400, 91 .base.cra_blocksize = SERPENT_BLOCK_SIZE, 92 .base.cra_ctxsize = sizeof(struct serpent_ctx), 93 .base.cra_module = THIS_MODULE, 94 .min_keysize = SERPENT_MIN_KEY_SIZE, 95 .max_keysize = SERPENT_MAX_KEY_SIZE, 96 .ivsize = SERPENT_BLOCK_SIZE, 97 .setkey = serpent_setkey_skcipher, 98 .encrypt = cbc_encrypt, 99 .decrypt = cbc_decrypt, 100 }, 101}; 102 103static int __init serpent_sse2_init(void) 104{ 105 if (!boot_cpu_has(X86_FEATURE_XMM2)) { 106 printk(KERN_INFO "SSE2 instructions are not detected.\n"); 107 return -ENODEV; 108 } 109 110 return crypto_register_skciphers(serpent_algs, 111 ARRAY_SIZE(serpent_algs)); 112} 113 114static void __exit serpent_sse2_exit(void) 115{ 116 crypto_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs)); 117} 118 119module_init(serpent_sse2_init); 120module_exit(serpent_sse2_exit); 121 122MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized"); 123MODULE_LICENSE("GPL"); 124MODULE_ALIAS_CRYPTO("serpent");