linux/arch/s390/crypto/sha_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Cryptographic API.
   4 *
   5 * s390 generic implementation of the SHA Secure Hash Algorithms.
   6 *
   7 * Copyright IBM Corp. 2007
   8 * Author(s): Jan Glauber (jang@de.ibm.com)
   9 */
  10
  11#include <crypto/internal/hash.h>
  12#include <linux/module.h>
  13#include <asm/cpacf.h>
  14#include "sha.h"
  15
  16int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
  17{
  18        struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
  19        unsigned int bsize = crypto_shash_blocksize(desc->tfm);
  20        unsigned int index, n;
  21
  22        /* how much is already in the buffer? */
  23        index = ctx->count & (bsize - 1);
  24        ctx->count += len;
  25
  26        if ((index + len) < bsize)
  27                goto store;
  28
  29        /* process one stored block */
  30        if (index) {
  31                memcpy(ctx->buf + index, data, bsize - index);
  32                cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize);
  33                data += bsize - index;
  34                len -= bsize - index;
  35                index = 0;
  36        }
  37
  38        /* process as many blocks as possible */
  39        if (len >= bsize) {
  40                n = len & ~(bsize - 1);
  41                cpacf_kimd(ctx->func, ctx->state, data, n);
  42                data += n;
  43                len -= n;
  44        }
  45store:
  46        if (len)
  47                memcpy(ctx->buf + index , data, len);
  48
  49        return 0;
  50}
  51EXPORT_SYMBOL_GPL(s390_sha_update);
  52
  53int s390_sha_final(struct shash_desc *desc, u8 *out)
  54{
  55        struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
  56        unsigned int bsize = crypto_shash_blocksize(desc->tfm);
  57        u64 bits;
  58        unsigned int index, end, plen;
  59
  60        /* SHA-512 uses 128 bit padding length */
  61        plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
  62
  63        /* must perform manual padding */
  64        index = ctx->count & (bsize - 1);
  65        end = (index < bsize - plen) ? bsize : (2 * bsize);
  66
  67        /* start pad with 1 */
  68        ctx->buf[index] = 0x80;
  69        index++;
  70
  71        /* pad with zeros */
  72        memset(ctx->buf + index, 0x00, end - index - 8);
  73
  74        /*
  75         * Append message length. Well, SHA-512 wants a 128 bit length value,
  76         * nevertheless we use u64, should be enough for now...
  77         */
  78        bits = ctx->count * 8;
  79        memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
  80        cpacf_kimd(ctx->func, ctx->state, ctx->buf, end);
  81
  82        /* copy digest to out */
  83        memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
  84        /* wipe context */
  85        memset(ctx, 0, sizeof *ctx);
  86
  87        return 0;
  88}
  89EXPORT_SYMBOL_GPL(s390_sha_final);
  90
  91MODULE_LICENSE("GPL");
  92MODULE_DESCRIPTION("s390 SHA cipher common functions");
  93