forked from Minki/linux
c7d4d259b7
The CPACF instructions are going be used in KVM as well, move the defines and the inline functions from arch/s390/crypt/crypt_s390.h to arch/s390/include/asm. Rename the header to cpacf.h and replace the crypt_s390_xxx names with cpacf_xxx. While we are at it, cleanup the header as well. The encoding for the CPACF operations is odd, there is an enum for each of the CPACF instructions with the hardware function code in the lower 8 bits of each entry and a software defined number for the CPACF instruction in the upper 8 bits. Remove the superfluous software number and replace the enums with simple defines. The crypt_s390_func_available() function tests for the presence of a specific CPACF operations. The new name of the function is cpacf_query and it works slightly different than before. It gets passed an opcode of an CPACF instruction and a function code for this instruction. The facility_mask parameter is gone, the opcode is used to find the correct MSA facility bit to check if the CPACF instruction itself is available. If it is the query function of the given instruction is used to test if the requested CPACF operation is present. Acked-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
107 lines
2.5 KiB
C
107 lines
2.5 KiB
C
/*
|
|
* Cryptographic API.
|
|
*
|
|
* s390 generic implementation of the SHA Secure Hash Algorithms.
|
|
*
|
|
* Copyright IBM Corp. 2007
|
|
* Author(s): Jan Glauber (jang@de.ibm.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
*/
|
|
|
|
#include <crypto/internal/hash.h>
|
|
#include <linux/module.h>
|
|
#include <asm/cpacf.h>
|
|
#include "sha.h"
|
|
|
|
int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
|
{
|
|
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
|
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
|
unsigned int index;
|
|
int ret;
|
|
|
|
/* how much is already in the buffer? */
|
|
index = ctx->count & (bsize - 1);
|
|
ctx->count += len;
|
|
|
|
if ((index + len) < bsize)
|
|
goto store;
|
|
|
|
/* process one stored block */
|
|
if (index) {
|
|
memcpy(ctx->buf + index, data, bsize - index);
|
|
ret = cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize);
|
|
if (ret != bsize)
|
|
return -EIO;
|
|
data += bsize - index;
|
|
len -= bsize - index;
|
|
index = 0;
|
|
}
|
|
|
|
/* process as many blocks as possible */
|
|
if (len >= bsize) {
|
|
ret = cpacf_kimd(ctx->func, ctx->state, data,
|
|
len & ~(bsize - 1));
|
|
if (ret != (len & ~(bsize - 1)))
|
|
return -EIO;
|
|
data += ret;
|
|
len -= ret;
|
|
}
|
|
store:
|
|
if (len)
|
|
memcpy(ctx->buf + index , data, len);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(s390_sha_update);
|
|
|
|
int s390_sha_final(struct shash_desc *desc, u8 *out)
|
|
{
|
|
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
|
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
|
u64 bits;
|
|
unsigned int index, end, plen;
|
|
int ret;
|
|
|
|
/* SHA-512 uses 128 bit padding length */
|
|
plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
|
|
|
|
/* must perform manual padding */
|
|
index = ctx->count & (bsize - 1);
|
|
end = (index < bsize - plen) ? bsize : (2 * bsize);
|
|
|
|
/* start pad with 1 */
|
|
ctx->buf[index] = 0x80;
|
|
index++;
|
|
|
|
/* pad with zeros */
|
|
memset(ctx->buf + index, 0x00, end - index - 8);
|
|
|
|
/*
|
|
* Append message length. Well, SHA-512 wants a 128 bit length value,
|
|
* nevertheless we use u64, should be enough for now...
|
|
*/
|
|
bits = ctx->count * 8;
|
|
memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
|
|
|
|
ret = cpacf_kimd(ctx->func, ctx->state, ctx->buf, end);
|
|
if (ret != end)
|
|
return -EIO;
|
|
|
|
/* copy digest to out */
|
|
memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
|
|
/* wipe context */
|
|
memset(ctx, 0, sizeof *ctx);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(s390_sha_final);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("s390 SHA cipher common functions");
|