linux/arch/sparc/crypto/aes_glue.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Glue code for AES encryption optimized for sparc64 crypto opcodes.
   3 *
   4 * This is based largely upon arch/x86/crypto/aesni-intel_glue.c
   5 *
   6 * Copyright (C) 2008, Intel Corp.
   7 *    Author: Huang Ying <ying.huang@intel.com>
   8 *
   9 * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD
  10 * interface for 64-bit kernels.
  11 *    Authors: Adrian Hoban <adrian.hoban@intel.com>
  12 *             Gabriele Paoloni <gabriele.paoloni@intel.com>
  13 *             Tadeusz Struk (tadeusz.struk@intel.com)
  14 *             Aidan O'Mahony (aidan.o.mahony@intel.com)
  15 *    Copyright (c) 2010, Intel Corporation.
  16 */
  17
  18#define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
  19
  20#include <linux/crypto.h>
  21#include <linux/init.h>
  22#include <linux/module.h>
  23#include <linux/mm.h>
  24#include <linux/types.h>
  25#include <crypto/algapi.h>
  26#include <crypto/aes.h>
  27#include <crypto/internal/skcipher.h>
  28
  29#include <asm/fpumacro.h>
  30#include <asm/pstate.h>
  31#include <asm/elf.h>
  32
  33#include "opcodes.h"
  34
  35struct aes_ops {
  36        void (*encrypt)(const u64 *key, const u32 *input, u32 *output);
  37        void (*decrypt)(const u64 *key, const u32 *input, u32 *output);
  38        void (*load_encrypt_keys)(const u64 *key);
  39        void (*load_decrypt_keys)(const u64 *key);
  40        void (*ecb_encrypt)(const u64 *key, const u64 *input, u64 *output,
  41                            unsigned int len);
  42        void (*ecb_decrypt)(const u64 *key, const u64 *input, u64 *output,
  43                            unsigned int len);
  44        void (*cbc_encrypt)(const u64 *key, const u64 *input, u64 *output,
  45                            unsigned int len, u64 *iv);
  46        void (*cbc_decrypt)(const u64 *key, const u64 *input, u64 *output,
  47                            unsigned int len, u64 *iv);
  48        void (*ctr_crypt)(const u64 *key, const u64 *input, u64 *output,
  49                          unsigned int len, u64 *iv);
  50};
  51
  52struct crypto_sparc64_aes_ctx {
  53        struct aes_ops *ops;
  54        u64 key[AES_MAX_KEYLENGTH / sizeof(u64)];
  55        u32 key_length;
  56        u32 expanded_key_length;
  57};
  58
  59extern void aes_sparc64_encrypt_128(const u64 *key, const u32 *input,
  60                                    u32 *output);
  61extern void aes_sparc64_encrypt_192(const u64 *key, const u32 *input,
  62                                    u32 *output);
  63extern void aes_sparc64_encrypt_256(const u64 *key, const u32 *input,
  64                                    u32 *output);
  65
  66extern void aes_sparc64_decrypt_128(const u64 *key, const u32 *input,
  67                                    u32 *output);
  68extern void aes_sparc64_decrypt_192(const u64 *key, const u32 *input,
  69                                    u32 *output);
  70extern void aes_sparc64_decrypt_256(const u64 *key, const u32 *input,
  71                                    u32 *output);
  72
  73extern void aes_sparc64_load_encrypt_keys_128(const u64 *key);
  74extern void aes_sparc64_load_encrypt_keys_192(const u64 *key);
  75extern void aes_sparc64_load_encrypt_keys_256(const u64 *key);
  76
  77extern void aes_sparc64_load_decrypt_keys_128(const u64 *key);
  78extern void aes_sparc64_load_decrypt_keys_192(const u64 *key);
  79extern void aes_sparc64_load_decrypt_keys_256(const u64 *key);
  80
  81extern void aes_sparc64_ecb_encrypt_128(const u64 *key, const u64 *input,
  82                                        u64 *output, unsigned int len);
  83extern void aes_sparc64_ecb_encrypt_192(const u64 *key, const u64 *input,
  84                                        u64 *output, unsigned int len);
  85extern void aes_sparc64_ecb_encrypt_256(const u64 *key, const u64 *input,
  86                                        u64 *output, unsigned int len);
  87
  88extern void aes_sparc64_ecb_decrypt_128(const u64 *key, const u64 *input,
  89                                        u64 *output, unsigned int len);
  90extern void aes_sparc64_ecb_decrypt_192(const u64 *key, const u64 *input,
  91                                        u64 *output, unsigned int len);
  92extern void aes_sparc64_ecb_decrypt_256(const u64 *key, const u64 *input,
  93                                        u64 *output, unsigned int len);
  94
  95extern void aes_sparc64_cbc_encrypt_128(const u64 *key, const u64 *input,
  96                                        u64 *output, unsigned int len,
  97                                        u64 *iv);
  98
  99extern void aes_sparc64_cbc_encrypt_192(const u64 *key, const u64 *input,
 100                                        u64 *output, unsigned int len,
 101                                        u64 *iv);
 102
 103extern void aes_sparc64_cbc_encrypt_256(const u64 *key, const u64 *input,
 104                                        u64 *output, unsigned int len,
 105                                        u64 *iv);
 106
 107extern void aes_sparc64_cbc_decrypt_128(const u64 *key, const u64 *input,
 108                                        u64 *output, unsigned int len,
 109                                        u64 *iv);
 110
 111extern void aes_sparc64_cbc_decrypt_192(const u64 *key, const u64 *input,
 112                                        u64 *output, unsigned int len,
 113                                        u64 *iv);
 114
 115extern void aes_sparc64_cbc_decrypt_256(const u64 *key, const u64 *input,
 116                                        u64 *output, unsigned int len,
 117                                        u64 *iv);
 118
 119extern void aes_sparc64_ctr_crypt_128(const u64 *key, const u64 *input,
 120                                      u64 *output, unsigned int len,
 121                                      u64 *iv);
 122extern void aes_sparc64_ctr_crypt_192(const u64 *key, const u64 *input,
 123                                      u64 *output, unsigned int len,
 124                                      u64 *iv);
 125extern void aes_sparc64_ctr_crypt_256(const u64 *key, const u64 *input,
 126                                      u64 *output, unsigned int len,
 127                                      u64 *iv);
 128
 129static struct aes_ops aes128_ops = {
 130        .encrypt                = aes_sparc64_encrypt_128,
 131        .decrypt                = aes_sparc64_decrypt_128,
 132        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_128,
 133        .load_decrypt_keys      = aes_sparc64_load_decrypt_keys_128,
 134        .ecb_encrypt            = aes_sparc64_ecb_encrypt_128,
 135        .ecb_decrypt            = aes_sparc64_ecb_decrypt_128,
 136        .cbc_encrypt            = aes_sparc64_cbc_encrypt_128,
 137        .cbc_decrypt            = aes_sparc64_cbc_decrypt_128,
 138        .ctr_crypt              = aes_sparc64_ctr_crypt_128,
 139};
 140
 141static struct aes_ops aes192_ops = {
 142        .encrypt                = aes_sparc64_encrypt_192,
 143        .decrypt                = aes_sparc64_decrypt_192,
 144        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_192,
 145        .load_decrypt_keys      = aes_sparc64_load_decrypt_keys_192,
 146        .ecb_encrypt            = aes_sparc64_ecb_encrypt_192,
 147        .ecb_decrypt            = aes_sparc64_ecb_decrypt_192,
 148        .cbc_encrypt            = aes_sparc64_cbc_encrypt_192,
 149        .cbc_decrypt            = aes_sparc64_cbc_decrypt_192,
 150        .ctr_crypt              = aes_sparc64_ctr_crypt_192,
 151};
 152
 153static struct aes_ops aes256_ops = {
 154        .encrypt                = aes_sparc64_encrypt_256,
 155        .decrypt                = aes_sparc64_decrypt_256,
 156        .load_encrypt_keys      = aes_sparc64_load_encrypt_keys_256,
 157        .load_decrypt_keys      = aes_sparc64_load_decrypt_keys_256,
 158        .ecb_encrypt            = aes_sparc64_ecb_encrypt_256,
 159        .ecb_decrypt            = aes_sparc64_ecb_decrypt_256,
 160        .cbc_encrypt            = aes_sparc64_cbc_encrypt_256,
 161        .cbc_decrypt            = aes_sparc64_cbc_decrypt_256,
 162        .ctr_crypt              = aes_sparc64_ctr_crypt_256,
 163};
 164
 165extern void aes_sparc64_key_expand(const u32 *in_key, u64 *output_key,
 166                                   unsigned int key_len);
 167
 168static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
 169                       unsigned int key_len)
 170{
 171        struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
 172        u32 *flags = &tfm->crt_flags;
 173
 174        switch (key_len) {
 175        case AES_KEYSIZE_128:
 176                ctx->expanded_key_length = 0xb0;
 177                ctx->ops = &aes128_ops;
 178                break;
 179
 180        case AES_KEYSIZE_192:
 181                ctx->expanded_key_length = 0xd0;
 182                ctx->ops = &aes192_ops;
 183                break;
 184
 185        case AES_KEYSIZE_256:
 186                ctx->expanded_key_length = 0xf0;
 187                ctx->ops = &aes256_ops;
 188                break;
 189
 190        default:
 191                *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
 192                return -EINVAL;
 193        }
 194
 195        aes_sparc64_key_expand((const u32 *)in_key, &ctx->key[0], key_len);
 196        ctx->key_length = key_len;
 197
 198        return 0;
 199}
 200
 201static int aes_set_key_skcipher(struct crypto_skcipher *tfm, const u8 *in_key,
 202                                unsigned int key_len)
 203{
 204        return aes_set_key(crypto_skcipher_tfm(tfm), in_key, key_len);
 205}
 206
 207static void crypto_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 208{
 209        struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
 210
 211        ctx->ops->encrypt(&ctx->key[0], (const u32 *) src, (u32 *) dst);
 212}
 213
 214static void crypto_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 215{
 216        struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
 217
 218        ctx->ops->decrypt(&ctx->key[0], (const u32 *) src, (u32 *) dst);
 219}
 220
 221static int ecb_encrypt(struct skcipher_request *req)
 222{
 223        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 224        const struct crypto_sparc64_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
 225        struct skcipher_walk walk;
 226        unsigned int nbytes;
 227        int err;
 228
 229        err = skcipher_walk_virt(&walk, req, true);
 230        if (err)
 231                return err;
 232
 233        ctx->ops->load_encrypt_keys(&ctx->key[0]);
 234        while ((nbytes = walk.nbytes) != 0) {
 235                ctx->ops->ecb_encrypt(&ctx->key[0], walk.src.virt.addr,
 236                                      walk.dst.virt.addr,
 237                                      round_down(nbytes, AES_BLOCK_SIZE));
 238                err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
 239        }
 240        fprs_write(0);
 241        return err;
 242}
 243
 244static int ecb_decrypt(struct skcipher_request *req)
 245{
 246        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 247        const struct crypto_sparc64_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
 248        const u64 *key_end;
 249        struct skcipher_walk walk;
 250        unsigned int nbytes;
 251        int err;
 252
 253        err = skcipher_walk_virt(&walk, req, true);
 254        if (err)
 255                return err;
 256
 257        ctx->ops->load_decrypt_keys(&ctx->key[0]);
 258        key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
 259        while ((nbytes = walk.nbytes) != 0) {
 260                ctx->ops->ecb_decrypt(key_end, walk.src.virt.addr,
 261                                      walk.dst.virt.addr,
 262                                      round_down(nbytes, AES_BLOCK_SIZE));
 263                err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
 264        }
 265        fprs_write(0);
 266
 267        return err;
 268}
 269
 270static int cbc_encrypt(struct skcipher_request *req)
 271{
 272        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 273        const struct crypto_sparc64_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
 274        struct skcipher_walk walk;
 275        unsigned int nbytes;
 276        int err;
 277
 278        err = skcipher_walk_virt(&walk, req, true);
 279        if (err)
 280                return err;
 281
 282        ctx->ops->load_encrypt_keys(&ctx->key[0]);
 283        while ((nbytes = walk.nbytes) != 0) {
 284                ctx->ops->cbc_encrypt(&ctx->key[0], walk.src.virt.addr,
 285                                      walk.dst.virt.addr,
 286                                      round_down(nbytes, AES_BLOCK_SIZE),
 287                                      walk.iv);
 288                err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
 289        }
 290        fprs_write(0);
 291        return err;
 292}
 293
 294static int cbc_decrypt(struct skcipher_request *req)
 295{
 296        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 297        const struct crypto_sparc64_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
 298        const u64 *key_end;
 299        struct skcipher_walk walk;
 300        unsigned int nbytes;
 301        int err;
 302
 303        err = skcipher_walk_virt(&walk, req, true);
 304        if (err)
 305                return err;
 306
 307        ctx->ops->load_decrypt_keys(&ctx->key[0]);
 308        key_end = &ctx->key[ctx->expanded_key_length / sizeof(u64)];
 309        while ((nbytes = walk.nbytes) != 0) {
 310                ctx->ops->cbc_decrypt(key_end, walk.src.virt.addr,
 311                                      walk.dst.virt.addr,
 312                                      round_down(nbytes, AES_BLOCK_SIZE),
 313                                      walk.iv);
 314                err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
 315        }
 316        fprs_write(0);
 317
 318        return err;
 319}
 320
 321static void ctr_crypt_final(const struct crypto_sparc64_aes_ctx *ctx,
 322                            struct skcipher_walk *walk)
 323{
 324        u8 *ctrblk = walk->iv;
 325        u64 keystream[AES_BLOCK_SIZE / sizeof(u64)];
 326        u8 *src = walk->src.virt.addr;
 327        u8 *dst = walk->dst.virt.addr;
 328        unsigned int nbytes = walk->nbytes;
 329
 330        ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk,
 331                              keystream, AES_BLOCK_SIZE);
 332        crypto_xor_cpy(dst, (u8 *) keystream, src, nbytes);
 333        crypto_inc(ctrblk, AES_BLOCK_SIZE);
 334}
 335
 336static int ctr_crypt(struct skcipher_request *req)
 337{
 338        struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 339        const struct crypto_sparc64_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
 340        struct skcipher_walk walk;
 341        unsigned int nbytes;
 342        int err;
 343
 344        err = skcipher_walk_virt(&walk, req, true);
 345        if (err)
 346                return err;
 347
 348        ctx->ops->load_encrypt_keys(&ctx->key[0]);
 349        while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
 350                ctx->ops->ctr_crypt(&ctx->key[0], walk.src.virt.addr,
 351                                    walk.dst.virt.addr,
 352                                    round_down(nbytes, AES_BLOCK_SIZE),
 353                                    walk.iv);
 354                err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
 355        }
 356        if (walk.nbytes) {
 357                ctr_crypt_final(ctx, &walk);
 358                err = skcipher_walk_done(&walk, 0);
 359        }
 360        fprs_write(0);
 361        return err;
 362}
 363
 364static struct crypto_alg cipher_alg = {
 365        .cra_name               = "aes",
 366        .cra_driver_name        = "aes-sparc64",
 367        .cra_priority           = SPARC_CR_OPCODE_PRIORITY,
 368        .cra_flags              = CRYPTO_ALG_TYPE_CIPHER,
 369        .cra_blocksize          = AES_BLOCK_SIZE,
 370        .cra_ctxsize            = sizeof(struct crypto_sparc64_aes_ctx),
 371        .cra_alignmask          = 3,
 372        .cra_module             = THIS_MODULE,
 373        .cra_u  = {
 374                .cipher = {
 375                        .cia_min_keysize        = AES_MIN_KEY_SIZE,
 376                        .cia_max_keysize        = AES_MAX_KEY_SIZE,
 377                        .cia_setkey             = aes_set_key,
 378                        .cia_encrypt            = crypto_aes_encrypt,
 379                        .cia_decrypt            = crypto_aes_decrypt
 380                }
 381        }
 382};
 383
 384static struct skcipher_alg skcipher_algs[] = {
 385        {
 386                .base.cra_name          = "ecb(aes)",
 387                .base.cra_driver_name   = "ecb-aes-sparc64",
 388                .base.cra_priority      = SPARC_CR_OPCODE_PRIORITY,
 389                .base.cra_blocksize     = AES_BLOCK_SIZE,
 390                .base.cra_ctxsize       = sizeof(struct crypto_sparc64_aes_ctx),
 391                .base.cra_alignmask     = 7,
 392                .base.cra_module        = THIS_MODULE,
 393                .min_keysize            = AES_MIN_KEY_SIZE,
 394                .max_keysize            = AES_MAX_KEY_SIZE,
 395                .setkey                 = aes_set_key_skcipher,
 396                .encrypt                = ecb_encrypt,
 397                .decrypt                = ecb_decrypt,
 398        }, {
 399                .base.cra_name          = "cbc(aes)",
 400                .base.cra_driver_name   = "cbc-aes-sparc64",
 401                .base.cra_priority      = SPARC_CR_OPCODE_PRIORITY,
 402                .base.cra_blocksize     = AES_BLOCK_SIZE,
 403                .base.cra_ctxsize       = sizeof(struct crypto_sparc64_aes_ctx),
 404                .base.cra_alignmask     = 7,
 405                .base.cra_module        = THIS_MODULE,
 406                .min_keysize            = AES_MIN_KEY_SIZE,
 407                .max_keysize            = AES_MAX_KEY_SIZE,
 408                .ivsize                 = AES_BLOCK_SIZE,
 409                .setkey                 = aes_set_key_skcipher,
 410                .encrypt                = cbc_encrypt,
 411                .decrypt                = cbc_decrypt,
 412        }, {
 413                .base.cra_name          = "ctr(aes)",
 414                .base.cra_driver_name   = "ctr-aes-sparc64",
 415                .base.cra_priority      = SPARC_CR_OPCODE_PRIORITY,
 416                .base.cra_blocksize     = 1,
 417                .base.cra_ctxsize       = sizeof(struct crypto_sparc64_aes_ctx),
 418                .base.cra_alignmask     = 7,
 419                .base.cra_module        = THIS_MODULE,
 420                .min_keysize            = AES_MIN_KEY_SIZE,
 421                .max_keysize            = AES_MAX_KEY_SIZE,
 422                .ivsize                 = AES_BLOCK_SIZE,
 423                .setkey                 = aes_set_key_skcipher,
 424                .encrypt                = ctr_crypt,
 425                .decrypt                = ctr_crypt,
 426                .chunksize              = AES_BLOCK_SIZE,
 427        }
 428};
 429
 430static bool __init sparc64_has_aes_opcode(void)
 431{
 432        unsigned long cfr;
 433
 434        if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
 435                return false;
 436
 437        __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
 438        if (!(cfr & CFR_AES))
 439                return false;
 440
 441        return true;
 442}
 443
 444static int __init aes_sparc64_mod_init(void)
 445{
 446        int err;
 447
 448        if (!sparc64_has_aes_opcode()) {
 449                pr_info("sparc64 aes opcodes not available.\n");
 450                return -ENODEV;
 451        }
 452        pr_info("Using sparc64 aes opcodes optimized AES implementation\n");
 453        err = crypto_register_alg(&cipher_alg);
 454        if (err)
 455                return err;
 456        err = crypto_register_skciphers(skcipher_algs,
 457                                        ARRAY_SIZE(skcipher_algs));
 458        if (err)
 459                crypto_unregister_alg(&cipher_alg);
 460        return err;
 461}
 462
 463static void __exit aes_sparc64_mod_fini(void)
 464{
 465        crypto_unregister_alg(&cipher_alg);
 466        crypto_unregister_skciphers(skcipher_algs, ARRAY_SIZE(skcipher_algs));
 467}
 468
 469module_init(aes_sparc64_mod_init);
 470module_exit(aes_sparc64_mod_fini);
 471
 472MODULE_LICENSE("GPL");
 473MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, sparc64 aes opcode accelerated");
 474
 475MODULE_ALIAS_CRYPTO("aes");
 476
 477#include "crop_devid.c"
 478