cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sha_common.c (2855B)


      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;
     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) * bsize;
     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
     53static int s390_crypto_shash_parmsize(int func)
     54{
     55	switch (func) {
     56	case CPACF_KLMD_SHA_1:
     57		return 20;
     58	case CPACF_KLMD_SHA_256:
     59		return 32;
     60	case CPACF_KLMD_SHA_512:
     61		return 64;
     62	case CPACF_KLMD_SHA3_224:
     63	case CPACF_KLMD_SHA3_256:
     64	case CPACF_KLMD_SHA3_384:
     65	case CPACF_KLMD_SHA3_512:
     66		return 200;
     67	default:
     68		return -EINVAL;
     69	}
     70}
     71
     72int s390_sha_final(struct shash_desc *desc, u8 *out)
     73{
     74	struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
     75	unsigned int bsize = crypto_shash_blocksize(desc->tfm);
     76	u64 bits;
     77	unsigned int n;
     78	int mbl_offset;
     79
     80	n = ctx->count % bsize;
     81	bits = ctx->count * 8;
     82	mbl_offset = s390_crypto_shash_parmsize(ctx->func);
     83	if (mbl_offset < 0)
     84		return -EINVAL;
     85
     86	mbl_offset = mbl_offset / sizeof(u32);
     87
     88	/* set total msg bit length (mbl) in CPACF parmblock */
     89	switch (ctx->func) {
     90	case CPACF_KLMD_SHA_1:
     91	case CPACF_KLMD_SHA_256:
     92		memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
     93		break;
     94	case CPACF_KLMD_SHA_512:
     95		/*
     96		 * the SHA512 parmblock has a 128-bit mbl field, clear
     97		 * high-order u64 field, copy bits to low-order u64 field
     98		 */
     99		memset(ctx->state + mbl_offset, 0x00, sizeof(bits));
    100		mbl_offset += sizeof(u64) / sizeof(u32);
    101		memcpy(ctx->state + mbl_offset, &bits, sizeof(bits));
    102		break;
    103	case CPACF_KLMD_SHA3_224:
    104	case CPACF_KLMD_SHA3_256:
    105	case CPACF_KLMD_SHA3_384:
    106	case CPACF_KLMD_SHA3_512:
    107		break;
    108	default:
    109		return -EINVAL;
    110	}
    111
    112	cpacf_klmd(ctx->func, ctx->state, ctx->buf, n);
    113
    114	/* copy digest to out */
    115	memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
    116	/* wipe context */
    117	memset(ctx, 0, sizeof *ctx);
    118
    119	return 0;
    120}
    121EXPORT_SYMBOL_GPL(s390_sha_final);
    122
    123MODULE_LICENSE("GPL");
    124MODULE_DESCRIPTION("s390 SHA cipher common functions");