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 <linux/crypto.h>
  17#include "sha.h"
  18#include "crypt_s390.h"
  19
  20void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
  21{
  22        struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
  23        unsigned int bsize = crypto_tfm_alg_blocksize(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}
  55EXPORT_SYMBOL_GPL(s390_sha_update);
  56
  57void s390_sha_final(struct crypto_tfm *tfm, u8 *out)
  58{
  59        struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
  60        unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
  61        u64 bits;
  62        unsigned int index, end, plen;
  63        int ret;
  64
  65        /* SHA-512 uses 128 bit padding length */
  66        plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
  67
  68        /* must perform manual padding */
  69        index = ctx->count & (bsize - 1);
  70        end = (index < bsize - plen) ? bsize : (2 * bsize);
  71
  72        /* start pad with 1 */
  73        ctx->buf[index] = 0x80;
  74        index++;
  75
  76        /* pad with zeros */
  77        memset(ctx->buf + index, 0x00, end - index - 8);
  78
  79        /*
  80         * Append message length. Well, SHA-512 wants a 128 bit lenght value,
  81         * nevertheless we use u64, should be enough for now...
  82         */
  83        bits = ctx->count * 8;
  84        memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
  85
  86        ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end);
  87        BUG_ON(ret != end);
  88
  89        /* copy digest to out */
  90        memcpy(out, ctx->state, crypto_hash_digestsize(crypto_hash_cast(tfm)));
  91        /* wipe context */
  92        memset(ctx, 0, sizeof *ctx);
  93}
  94EXPORT_SYMBOL_GPL(s390_sha_final);
  95
  96MODULE_LICENSE("GPL");
  97MODULE_DESCRIPTION("s390 SHA cipher common functions");
  98