root/arch/sparc/crypto/sha256_glue.c

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

DEFINITIONS

This source file includes following definitions.
  1. sha224_sparc64_init
  2. sha256_sparc64_init
  3. __sha256_sparc64_update
  4. sha256_sparc64_update
  5. sha256_sparc64_final
  6. sha224_sparc64_final
  7. sha256_sparc64_export
  8. sha256_sparc64_import
  9. sparc64_has_sha256_opcode
  10. sha256_sparc64_mod_init
  11. sha256_sparc64_mod_fini

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Glue code for SHA256 hashing optimized for sparc64 crypto opcodes.
   3  *
   4  * This is based largely upon crypto/sha256_generic.c
   5  *
   6  * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
   7  * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
   8  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
   9  * SHA224 Support Copyright 2007 Intel Corporation <jonathan.lynch@intel.com>
  10  */
  11 
  12 #define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
  13 
  14 #include <crypto/internal/hash.h>
  15 #include <linux/init.h>
  16 #include <linux/module.h>
  17 #include <linux/mm.h>
  18 #include <linux/cryptohash.h>
  19 #include <linux/types.h>
  20 #include <crypto/sha.h>
  21 
  22 #include <asm/pstate.h>
  23 #include <asm/elf.h>
  24 
  25 #include "opcodes.h"
  26 
  27 asmlinkage void sha256_sparc64_transform(u32 *digest, const char *data,
  28                                          unsigned int rounds);
  29 
  30 static int sha224_sparc64_init(struct shash_desc *desc)
  31 {
  32         struct sha256_state *sctx = shash_desc_ctx(desc);
  33         sctx->state[0] = SHA224_H0;
  34         sctx->state[1] = SHA224_H1;
  35         sctx->state[2] = SHA224_H2;
  36         sctx->state[3] = SHA224_H3;
  37         sctx->state[4] = SHA224_H4;
  38         sctx->state[5] = SHA224_H5;
  39         sctx->state[6] = SHA224_H6;
  40         sctx->state[7] = SHA224_H7;
  41         sctx->count = 0;
  42 
  43         return 0;
  44 }
  45 
  46 static int sha256_sparc64_init(struct shash_desc *desc)
  47 {
  48         struct sha256_state *sctx = shash_desc_ctx(desc);
  49         sctx->state[0] = SHA256_H0;
  50         sctx->state[1] = SHA256_H1;
  51         sctx->state[2] = SHA256_H2;
  52         sctx->state[3] = SHA256_H3;
  53         sctx->state[4] = SHA256_H4;
  54         sctx->state[5] = SHA256_H5;
  55         sctx->state[6] = SHA256_H6;
  56         sctx->state[7] = SHA256_H7;
  57         sctx->count = 0;
  58 
  59         return 0;
  60 }
  61 
  62 static void __sha256_sparc64_update(struct sha256_state *sctx, const u8 *data,
  63                                     unsigned int len, unsigned int partial)
  64 {
  65         unsigned int done = 0;
  66 
  67         sctx->count += len;
  68         if (partial) {
  69                 done = SHA256_BLOCK_SIZE - partial;
  70                 memcpy(sctx->buf + partial, data, done);
  71                 sha256_sparc64_transform(sctx->state, sctx->buf, 1);
  72         }
  73         if (len - done >= SHA256_BLOCK_SIZE) {
  74                 const unsigned int rounds = (len - done) / SHA256_BLOCK_SIZE;
  75 
  76                 sha256_sparc64_transform(sctx->state, data + done, rounds);
  77                 done += rounds * SHA256_BLOCK_SIZE;
  78         }
  79 
  80         memcpy(sctx->buf, data + done, len - done);
  81 }
  82 
  83 static int sha256_sparc64_update(struct shash_desc *desc, const u8 *data,
  84                                  unsigned int len)
  85 {
  86         struct sha256_state *sctx = shash_desc_ctx(desc);
  87         unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  88 
  89         /* Handle the fast case right here */
  90         if (partial + len < SHA256_BLOCK_SIZE) {
  91                 sctx->count += len;
  92                 memcpy(sctx->buf + partial, data, len);
  93         } else
  94                 __sha256_sparc64_update(sctx, data, len, partial);
  95 
  96         return 0;
  97 }
  98 
  99 static int sha256_sparc64_final(struct shash_desc *desc, u8 *out)
 100 {
 101         struct sha256_state *sctx = shash_desc_ctx(desc);
 102         unsigned int i, index, padlen;
 103         __be32 *dst = (__be32 *)out;
 104         __be64 bits;
 105         static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
 106 
 107         bits = cpu_to_be64(sctx->count << 3);
 108 
 109         /* Pad out to 56 mod 64 and append length */
 110         index = sctx->count % SHA256_BLOCK_SIZE;
 111         padlen = (index < 56) ? (56 - index) : ((SHA256_BLOCK_SIZE+56) - index);
 112 
 113         /* We need to fill a whole block for __sha256_sparc64_update() */
 114         if (padlen <= 56) {
 115                 sctx->count += padlen;
 116                 memcpy(sctx->buf + index, padding, padlen);
 117         } else {
 118                 __sha256_sparc64_update(sctx, padding, padlen, index);
 119         }
 120         __sha256_sparc64_update(sctx, (const u8 *)&bits, sizeof(bits), 56);
 121 
 122         /* Store state in digest */
 123         for (i = 0; i < 8; i++)
 124                 dst[i] = cpu_to_be32(sctx->state[i]);
 125 
 126         /* Wipe context */
 127         memset(sctx, 0, sizeof(*sctx));
 128 
 129         return 0;
 130 }
 131 
 132 static int sha224_sparc64_final(struct shash_desc *desc, u8 *hash)
 133 {
 134         u8 D[SHA256_DIGEST_SIZE];
 135 
 136         sha256_sparc64_final(desc, D);
 137 
 138         memcpy(hash, D, SHA224_DIGEST_SIZE);
 139         memzero_explicit(D, SHA256_DIGEST_SIZE);
 140 
 141         return 0;
 142 }
 143 
 144 static int sha256_sparc64_export(struct shash_desc *desc, void *out)
 145 {
 146         struct sha256_state *sctx = shash_desc_ctx(desc);
 147 
 148         memcpy(out, sctx, sizeof(*sctx));
 149         return 0;
 150 }
 151 
 152 static int sha256_sparc64_import(struct shash_desc *desc, const void *in)
 153 {
 154         struct sha256_state *sctx = shash_desc_ctx(desc);
 155 
 156         memcpy(sctx, in, sizeof(*sctx));
 157         return 0;
 158 }
 159 
 160 static struct shash_alg sha256 = {
 161         .digestsize     =       SHA256_DIGEST_SIZE,
 162         .init           =       sha256_sparc64_init,
 163         .update         =       sha256_sparc64_update,
 164         .final          =       sha256_sparc64_final,
 165         .export         =       sha256_sparc64_export,
 166         .import         =       sha256_sparc64_import,
 167         .descsize       =       sizeof(struct sha256_state),
 168         .statesize      =       sizeof(struct sha256_state),
 169         .base           =       {
 170                 .cra_name       =       "sha256",
 171                 .cra_driver_name=       "sha256-sparc64",
 172                 .cra_priority   =       SPARC_CR_OPCODE_PRIORITY,
 173                 .cra_blocksize  =       SHA256_BLOCK_SIZE,
 174                 .cra_module     =       THIS_MODULE,
 175         }
 176 };
 177 
 178 static struct shash_alg sha224 = {
 179         .digestsize     =       SHA224_DIGEST_SIZE,
 180         .init           =       sha224_sparc64_init,
 181         .update         =       sha256_sparc64_update,
 182         .final          =       sha224_sparc64_final,
 183         .descsize       =       sizeof(struct sha256_state),
 184         .base           =       {
 185                 .cra_name       =       "sha224",
 186                 .cra_driver_name=       "sha224-sparc64",
 187                 .cra_priority   =       SPARC_CR_OPCODE_PRIORITY,
 188                 .cra_blocksize  =       SHA224_BLOCK_SIZE,
 189                 .cra_module     =       THIS_MODULE,
 190         }
 191 };
 192 
 193 static bool __init sparc64_has_sha256_opcode(void)
 194 {
 195         unsigned long cfr;
 196 
 197         if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
 198                 return false;
 199 
 200         __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
 201         if (!(cfr & CFR_SHA256))
 202                 return false;
 203 
 204         return true;
 205 }
 206 
 207 static int __init sha256_sparc64_mod_init(void)
 208 {
 209         if (sparc64_has_sha256_opcode()) {
 210                 int ret = crypto_register_shash(&sha224);
 211                 if (ret < 0)
 212                         return ret;
 213 
 214                 ret = crypto_register_shash(&sha256);
 215                 if (ret < 0) {
 216                         crypto_unregister_shash(&sha224);
 217                         return ret;
 218                 }
 219 
 220                 pr_info("Using sparc64 sha256 opcode optimized SHA-256/SHA-224 implementation\n");
 221                 return 0;
 222         }
 223         pr_info("sparc64 sha256 opcode not available.\n");
 224         return -ENODEV;
 225 }
 226 
 227 static void __exit sha256_sparc64_mod_fini(void)
 228 {
 229         crypto_unregister_shash(&sha224);
 230         crypto_unregister_shash(&sha256);
 231 }
 232 
 233 module_init(sha256_sparc64_mod_init);
 234 module_exit(sha256_sparc64_mod_fini);
 235 
 236 MODULE_LICENSE("GPL");
 237 MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 opcode accelerated");
 238 
 239 MODULE_ALIAS_CRYPTO("sha224");
 240 MODULE_ALIAS_CRYPTO("sha256");
 241 
 242 #include "crop_devid.c"

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