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                index = 0;
  42        }
  43
  44        /* process as many blocks as possible */
  45        if (len >= bsize) {
  46                ret = crypt_s390_kimd(ctx->func, ctx->state, data,
  47                                      len & ~(bsize - 1));
  48                BUG_ON(ret != (len & ~(bsize - 1)));
  49                data += ret;
  50                len -= ret;
  51        }
  52store:
  53        if (len)
  54                memcpy(ctx->buf + index , data, len);
  55
  56        return 0;
  57}
  58EXPORT_SYMBOL_GPL(s390_sha_update);
  59
  60int s390_sha_final(struct shash_desc *desc, u8 *out)
  61{
  62        struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
  63        unsigned int bsize = crypto_shash_blocksize(desc->tfm);
  64        u64 bits;
  65        unsigned int index, end, plen;
  66        int ret;
  67
  68        /* SHA-512 uses 128 bit padding length */
  69        plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
  70
  71        /* must perform manual padding */
  72        index = ctx->count & (bsize - 1);
  73        end = (index < bsize - plen) ? bsize : (2 * bsize);
  74
  75        /* start pad with 1 */
  76        ctx->buf[index] = 0x80;
  77        index++;
  78
  79        /* pad with zeros */
  80        memset(ctx->buf + index, 0x00, end - index - 8);
  81
  82        /*
  83         * Append message length. Well, SHA-512 wants a 128 bit length value,
  84         * nevertheless we use u64, should be enough for now...
  85         */
  86        bits = ctx->count * 8;
  87        memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
  88
  89        ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end);
  90        BUG_ON(ret != end);
  91
  92        /* copy digest to out */
  93        memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
  94        /* wipe context */
  95        memset(ctx, 0, sizeof *ctx);
  96
  97        return 0;
  98}
  99EXPORT_SYMBOL_GPL(s390_sha_final);
 100
 101MODULE_LICENSE("GPL");
 102MODULE_DESCRIPTION("s390 SHA cipher common functions");
 103