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