^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Glue code for CAMELLIA encryption optimized for sparc64 crypto opcodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 David S. Miller <davem@davemloft.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/crypto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <crypto/algapi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <crypto/internal/skcipher.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/fpumacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/pstate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "opcodes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CAMELLIA_MIN_KEY_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CAMELLIA_MAX_KEY_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CAMELLIA_BLOCK_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CAMELLIA_TABLE_BYTE_LEN 272
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct camellia_sparc64_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u64 encrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u64 decrypt_key[CAMELLIA_TABLE_BYTE_LEN / sizeof(u64)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) extern void camellia_sparc64_key_expand(const u32 *in_key, u64 *encrypt_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned int key_len, u64 *decrypt_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int camellia_set_key(struct crypto_tfm *tfm, const u8 *_in_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const u32 *in_key = (const u32 *) _in_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (key_len != 16 && key_len != 24 && key_len != 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ctx->key_len = key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) camellia_sparc64_key_expand(in_key, &ctx->encrypt_key[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) key_len, &ctx->decrypt_key[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int camellia_set_key_skcipher(struct crypto_skcipher *tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) const u8 *in_key, unsigned int key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return camellia_set_key(crypto_skcipher_tfm(tfm), in_key, key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) extern void camellia_sparc64_crypt(const u64 *key, const u32 *input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u32 *output, unsigned int key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void camellia_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) camellia_sparc64_crypt(&ctx->encrypt_key[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) (const u32 *) src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (u32 *) dst, ctx->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void camellia_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) camellia_sparc64_crypt(&ctx->decrypt_key[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (const u32 *) src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (u32 *) dst, ctx->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) extern void camellia_sparc64_load_keys(const u64 *key, unsigned int key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) typedef void ecb_crypt_op(const u64 *input, u64 *output, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const u64 *key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) extern ecb_crypt_op camellia_sparc64_ecb_crypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) extern ecb_crypt_op camellia_sparc64_ecb_crypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int __ecb_crypt(struct skcipher_request *req, bool encrypt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) const struct camellia_sparc64_ctx *ctx = crypto_skcipher_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct skcipher_walk walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ecb_crypt_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const u64 *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned int nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) op = camellia_sparc64_ecb_crypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ctx->key_len != 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) op = camellia_sparc64_ecb_crypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err = skcipher_walk_virt(&walk, req, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (encrypt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) key = &ctx->encrypt_key[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) key = &ctx->decrypt_key[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) camellia_sparc64_load_keys(key, ctx->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) while ((nbytes = walk.nbytes) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) op(walk.src.virt.addr, walk.dst.virt.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) round_down(nbytes, CAMELLIA_BLOCK_SIZE), key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) err = skcipher_walk_done(&walk, nbytes % CAMELLIA_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) fprs_write(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int ecb_encrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return __ecb_crypt(req, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int ecb_decrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return __ecb_crypt(req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) typedef void cbc_crypt_op(const u64 *input, u64 *output, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const u64 *key, u64 *iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) extern cbc_crypt_op camellia_sparc64_cbc_encrypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) extern cbc_crypt_op camellia_sparc64_cbc_encrypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) extern cbc_crypt_op camellia_sparc64_cbc_decrypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) extern cbc_crypt_op camellia_sparc64_cbc_decrypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int cbc_encrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) const struct camellia_sparc64_ctx *ctx = crypto_skcipher_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct skcipher_walk walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cbc_crypt_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const u64 *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) op = camellia_sparc64_cbc_encrypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ctx->key_len != 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) op = camellia_sparc64_cbc_encrypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) err = skcipher_walk_virt(&walk, req, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) key = &ctx->encrypt_key[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) camellia_sparc64_load_keys(key, ctx->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) while ((nbytes = walk.nbytes) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) op(walk.src.virt.addr, walk.dst.virt.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) round_down(nbytes, CAMELLIA_BLOCK_SIZE), key, walk.iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) err = skcipher_walk_done(&walk, nbytes % CAMELLIA_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) fprs_write(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int cbc_decrypt(struct skcipher_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const struct camellia_sparc64_ctx *ctx = crypto_skcipher_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct skcipher_walk walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) cbc_crypt_op *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) const u64 *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) op = camellia_sparc64_cbc_decrypt_3_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ctx->key_len != 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) op = camellia_sparc64_cbc_decrypt_4_grand_rounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err = skcipher_walk_virt(&walk, req, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) key = &ctx->decrypt_key[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) camellia_sparc64_load_keys(key, ctx->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) while ((nbytes = walk.nbytes) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) op(walk.src.virt.addr, walk.dst.virt.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) round_down(nbytes, CAMELLIA_BLOCK_SIZE), key, walk.iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) err = skcipher_walk_done(&walk, nbytes % CAMELLIA_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) fprs_write(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static struct crypto_alg cipher_alg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .cra_name = "camellia",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .cra_driver_name = "camellia-sparc64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .cra_priority = SPARC_CR_OPCODE_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .cra_blocksize = CAMELLIA_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .cra_alignmask = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .cra_u = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .cipher = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .cia_setkey = camellia_set_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .cia_encrypt = camellia_encrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .cia_decrypt = camellia_decrypt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static struct skcipher_alg skcipher_algs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .base.cra_name = "ecb(camellia)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .base.cra_driver_name = "ecb-camellia-sparc64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .base.cra_priority = SPARC_CR_OPCODE_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .base.cra_blocksize = CAMELLIA_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .base.cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .base.cra_alignmask = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .base.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .min_keysize = CAMELLIA_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .max_keysize = CAMELLIA_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .setkey = camellia_set_key_skcipher,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .encrypt = ecb_encrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .decrypt = ecb_decrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .base.cra_name = "cbc(camellia)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .base.cra_driver_name = "cbc-camellia-sparc64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .base.cra_priority = SPARC_CR_OPCODE_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .base.cra_blocksize = CAMELLIA_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .base.cra_ctxsize = sizeof(struct camellia_sparc64_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .base.cra_alignmask = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .base.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .min_keysize = CAMELLIA_MIN_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .max_keysize = CAMELLIA_MAX_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .ivsize = CAMELLIA_BLOCK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .setkey = camellia_set_key_skcipher,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .encrypt = cbc_encrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .decrypt = cbc_decrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static bool __init sparc64_has_camellia_opcode(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned long cfr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!(cfr & CFR_CAMELLIA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int __init camellia_sparc64_mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!sparc64_has_camellia_opcode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pr_info("sparc64 camellia opcodes not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) pr_info("Using sparc64 camellia opcodes optimized CAMELLIA implementation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) err = crypto_register_alg(&cipher_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) err = crypto_register_skciphers(skcipher_algs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ARRAY_SIZE(skcipher_algs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) crypto_unregister_alg(&cipher_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void __exit camellia_sparc64_mod_fini(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) crypto_unregister_alg(&cipher_alg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) crypto_unregister_skciphers(skcipher_algs, ARRAY_SIZE(skcipher_algs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) module_init(camellia_sparc64_mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) module_exit(camellia_sparc64_mod_fini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) MODULE_ALIAS_CRYPTO("camellia");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #include "crop_devid.c"