linux/arch/arm/crypto/sha256_neon_glue.c
<<
>>
Prefs
   1/*
   2 * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
   3 * using NEON instructions.
   4 *
   5 * Copyright © 2015 Google Inc.
   6 *
   7 * This file is based on sha512_neon_glue.c:
   8 *   Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
   9 *
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of the GNU General Public License as published by the Free
  12 * Software Foundation; either version 2 of the License, or (at your option)
  13 * any later version.
  14 *
  15 */
  16
  17#include <crypto/internal/hash.h>
  18#include <linux/cryptohash.h>
  19#include <linux/types.h>
  20#include <linux/string.h>
  21#include <crypto/sha.h>
  22#include <crypto/sha256_base.h>
  23#include <asm/byteorder.h>
  24#include <asm/simd.h>
  25#include <asm/neon.h>
  26
  27#include "sha256_glue.h"
  28
  29asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data,
  30                                             unsigned int num_blks);
  31
  32static int sha256_update(struct shash_desc *desc, const u8 *data,
  33                         unsigned int len)
  34{
  35        struct sha256_state *sctx = shash_desc_ctx(desc);
  36
  37        if (!may_use_simd() ||
  38            (sctx->count % SHA256_BLOCK_SIZE) + len < SHA256_BLOCK_SIZE)
  39                return crypto_sha256_arm_update(desc, data, len);
  40
  41        kernel_neon_begin();
  42        sha256_base_do_update(desc, data, len,
  43                        (sha256_block_fn *)sha256_block_data_order_neon);
  44        kernel_neon_end();
  45
  46        return 0;
  47}
  48
  49static int sha256_finup(struct shash_desc *desc, const u8 *data,
  50                        unsigned int len, u8 *out)
  51{
  52        if (!may_use_simd())
  53                return crypto_sha256_arm_finup(desc, data, len, out);
  54
  55        kernel_neon_begin();
  56        if (len)
  57                sha256_base_do_update(desc, data, len,
  58                        (sha256_block_fn *)sha256_block_data_order_neon);
  59        sha256_base_do_finalize(desc,
  60                        (sha256_block_fn *)sha256_block_data_order_neon);
  61        kernel_neon_end();
  62
  63        return sha256_base_finish(desc, out);
  64}
  65
  66static int sha256_final(struct shash_desc *desc, u8 *out)
  67{
  68        return sha256_finup(desc, NULL, 0, out);
  69}
  70
  71struct shash_alg sha256_neon_algs[] = { {
  72        .digestsize     =       SHA256_DIGEST_SIZE,
  73        .init           =       sha256_base_init,
  74        .update         =       sha256_update,
  75        .final          =       sha256_final,
  76        .finup          =       sha256_finup,
  77        .descsize       =       sizeof(struct sha256_state),
  78        .base           =       {
  79                .cra_name       =       "sha256",
  80                .cra_driver_name =      "sha256-neon",
  81                .cra_priority   =       250,
  82                .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
  83                .cra_blocksize  =       SHA256_BLOCK_SIZE,
  84                .cra_module     =       THIS_MODULE,
  85        }
  86}, {
  87        .digestsize     =       SHA224_DIGEST_SIZE,
  88        .init           =       sha224_base_init,
  89        .update         =       sha256_update,
  90        .final          =       sha256_final,
  91        .finup          =       sha256_finup,
  92        .descsize       =       sizeof(struct sha256_state),
  93        .base           =       {
  94                .cra_name       =       "sha224",
  95                .cra_driver_name =      "sha224-neon",
  96                .cra_priority   =       250,
  97                .cra_flags      =       CRYPTO_ALG_TYPE_SHASH,
  98                .cra_blocksize  =       SHA224_BLOCK_SIZE,
  99                .cra_module     =       THIS_MODULE,
 100        }
 101} };
 102