root/arch/arm64/crypto/sha2-ce-glue.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sha256_ce_update
  2. sha256_ce_finup
  3. sha256_ce_final
  4. sha2_ce_mod_init
  5. sha2_ce_mod_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
   4  *
   5  * Copyright (C) 2014 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
   6  */
   7 
   8 #include <asm/neon.h>
   9 #include <asm/simd.h>
  10 #include <asm/unaligned.h>
  11 #include <crypto/internal/hash.h>
  12 #include <crypto/internal/simd.h>
  13 #include <crypto/sha.h>
  14 #include <crypto/sha256_base.h>
  15 #include <linux/cpufeature.h>
  16 #include <linux/crypto.h>
  17 #include <linux/module.h>
  18 
  19 MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
  20 MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  21 MODULE_LICENSE("GPL v2");
  22 
  23 struct sha256_ce_state {
  24         struct sha256_state     sst;
  25         u32                     finalize;
  26 };
  27 
  28 asmlinkage void sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src,
  29                                   int blocks);
  30 
  31 const u32 sha256_ce_offsetof_count = offsetof(struct sha256_ce_state,
  32                                               sst.count);
  33 const u32 sha256_ce_offsetof_finalize = offsetof(struct sha256_ce_state,
  34                                                  finalize);
  35 
  36 asmlinkage void sha256_block_data_order(u32 *digest, u8 const *src, int blocks);
  37 
  38 static int sha256_ce_update(struct shash_desc *desc, const u8 *data,
  39                             unsigned int len)
  40 {
  41         struct sha256_ce_state *sctx = shash_desc_ctx(desc);
  42 
  43         if (!crypto_simd_usable())
  44                 return sha256_base_do_update(desc, data, len,
  45                                 (sha256_block_fn *)sha256_block_data_order);
  46 
  47         sctx->finalize = 0;
  48         kernel_neon_begin();
  49         sha256_base_do_update(desc, data, len,
  50                               (sha256_block_fn *)sha2_ce_transform);
  51         kernel_neon_end();
  52 
  53         return 0;
  54 }
  55 
  56 static int sha256_ce_finup(struct shash_desc *desc, const u8 *data,
  57                            unsigned int len, u8 *out)
  58 {
  59         struct sha256_ce_state *sctx = shash_desc_ctx(desc);
  60         bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE) && len;
  61 
  62         if (!crypto_simd_usable()) {
  63                 if (len)
  64                         sha256_base_do_update(desc, data, len,
  65                                 (sha256_block_fn *)sha256_block_data_order);
  66                 sha256_base_do_finalize(desc,
  67                                 (sha256_block_fn *)sha256_block_data_order);
  68                 return sha256_base_finish(desc, out);
  69         }
  70 
  71         /*
  72          * Allow the asm code to perform the finalization if there is no
  73          * partial data and the input is a round multiple of the block size.
  74          */
  75         sctx->finalize = finalize;
  76 
  77         kernel_neon_begin();
  78         sha256_base_do_update(desc, data, len,
  79                               (sha256_block_fn *)sha2_ce_transform);
  80         if (!finalize)
  81                 sha256_base_do_finalize(desc,
  82                                         (sha256_block_fn *)sha2_ce_transform);
  83         kernel_neon_end();
  84         return sha256_base_finish(desc, out);
  85 }
  86 
  87 static int sha256_ce_final(struct shash_desc *desc, u8 *out)
  88 {
  89         struct sha256_ce_state *sctx = shash_desc_ctx(desc);
  90 
  91         if (!crypto_simd_usable()) {
  92                 sha256_base_do_finalize(desc,
  93                                 (sha256_block_fn *)sha256_block_data_order);
  94                 return sha256_base_finish(desc, out);
  95         }
  96 
  97         sctx->finalize = 0;
  98         kernel_neon_begin();
  99         sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform);
 100         kernel_neon_end();
 101         return sha256_base_finish(desc, out);
 102 }
 103 
 104 static struct shash_alg algs[] = { {
 105         .init                   = sha224_base_init,
 106         .update                 = sha256_ce_update,
 107         .final                  = sha256_ce_final,
 108         .finup                  = sha256_ce_finup,
 109         .descsize               = sizeof(struct sha256_ce_state),
 110         .digestsize             = SHA224_DIGEST_SIZE,
 111         .base                   = {
 112                 .cra_name               = "sha224",
 113                 .cra_driver_name        = "sha224-ce",
 114                 .cra_priority           = 200,
 115                 .cra_blocksize          = SHA256_BLOCK_SIZE,
 116                 .cra_module             = THIS_MODULE,
 117         }
 118 }, {
 119         .init                   = sha256_base_init,
 120         .update                 = sha256_ce_update,
 121         .final                  = sha256_ce_final,
 122         .finup                  = sha256_ce_finup,
 123         .descsize               = sizeof(struct sha256_ce_state),
 124         .digestsize             = SHA256_DIGEST_SIZE,
 125         .base                   = {
 126                 .cra_name               = "sha256",
 127                 .cra_driver_name        = "sha256-ce",
 128                 .cra_priority           = 200,
 129                 .cra_blocksize          = SHA256_BLOCK_SIZE,
 130                 .cra_module             = THIS_MODULE,
 131         }
 132 } };
 133 
 134 static int __init sha2_ce_mod_init(void)
 135 {
 136         return crypto_register_shashes(algs, ARRAY_SIZE(algs));
 137 }
 138 
 139 static void __exit sha2_ce_mod_fini(void)
 140 {
 141         crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
 142 }
 143 
 144 module_cpu_feature_match(SHA2, sha2_ce_mod_init);
 145 module_exit(sha2_ce_mod_fini);

/* [<][>][^][v][top][bottom][index][help] */