sha256_s390.c 3.39 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0+
Jan Glauber's avatar
Jan Glauber committed
2 3 4
/*
 * Cryptographic API.
 *
5
 * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm.
Jan Glauber's avatar
Jan Glauber committed
6 7
 *
 * s390 Version:
8
 *   Copyright IBM Corp. 2005, 2011
Jan Glauber's avatar
Jan Glauber committed
9 10
 *   Author(s): Jan Glauber (jang@de.ibm.com)
 */
11
#include <crypto/internal/hash.h>
Jan Glauber's avatar
Jan Glauber committed
12 13
#include <linux/init.h>
#include <linux/module.h>
14
#include <linux/cpufeature.h>
15
#include <crypto/sha.h>
16
#include <asm/cpacf.h>
Jan Glauber's avatar
Jan Glauber committed
17

18
#include "sha.h"
Jan Glauber's avatar
Jan Glauber committed
19

20
static int s390_sha256_init(struct shash_desc *desc)
Jan Glauber's avatar
Jan Glauber committed
21
{
22
	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
Jan Glauber's avatar
Jan Glauber committed
23

24 25 26 27 28 29 30 31
	sctx->state[0] = SHA256_H0;
	sctx->state[1] = SHA256_H1;
	sctx->state[2] = SHA256_H2;
	sctx->state[3] = SHA256_H3;
	sctx->state[4] = SHA256_H4;
	sctx->state[5] = SHA256_H5;
	sctx->state[6] = SHA256_H6;
	sctx->state[7] = SHA256_H7;
Jan Glauber's avatar
Jan Glauber committed
32
	sctx->count = 0;
33
	sctx->func = CPACF_KIMD_SHA_256;
34 35

	return 0;
Jan Glauber's avatar
Jan Glauber committed
36 37
}

38 39 40 41 42 43 44 45 46 47 48
static int sha256_export(struct shash_desc *desc, void *out)
{
	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
	struct sha256_state *octx = out;

	octx->count = sctx->count;
	memcpy(octx->state, sctx->state, sizeof(octx->state));
	memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
	return 0;
}

49
static int sha256_import(struct shash_desc *desc, const void *in)
50
{
51
	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
52
	const struct sha256_state *ictx = in;
53 54 55 56

	sctx->count = ictx->count;
	memcpy(sctx->state, ictx->state, sizeof(ictx->state));
	memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
57
	sctx->func = CPACF_KIMD_SHA_256;
58 59 60
	return 0;
}

61
static struct shash_alg sha256_alg = {
62
	.digestsize	=	SHA256_DIGEST_SIZE,
63
	.init		=	s390_sha256_init,
64 65
	.update		=	s390_sha_update,
	.final		=	s390_sha_final,
66 67
	.export		=	sha256_export,
	.import		=	sha256_import,
68
	.descsize	=	sizeof(struct s390_sha_ctx),
69
	.statesize	=	sizeof(struct sha256_state),
70 71 72
	.base		=	{
		.cra_name	=	"sha256",
		.cra_driver_name=	"sha256-s390",
73
		.cra_priority	=	300,
74 75 76
		.cra_blocksize	=	SHA256_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
Jan Glauber's avatar
Jan Glauber committed
77 78
};

79
static int s390_sha224_init(struct shash_desc *desc)
Jan Glauber's avatar
Jan Glauber committed
80
{
81 82 83 84 85 86 87 88 89 90 91
	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);

	sctx->state[0] = SHA224_H0;
	sctx->state[1] = SHA224_H1;
	sctx->state[2] = SHA224_H2;
	sctx->state[3] = SHA224_H3;
	sctx->state[4] = SHA224_H4;
	sctx->state[5] = SHA224_H5;
	sctx->state[6] = SHA224_H6;
	sctx->state[7] = SHA224_H7;
	sctx->count = 0;
92
	sctx->func = CPACF_KIMD_SHA_256;
93 94 95 96 97 98

	return 0;
}

static struct shash_alg sha224_alg = {
	.digestsize	=	SHA224_DIGEST_SIZE,
99
	.init		=	s390_sha224_init,
100 101 102 103 104 105 106 107 108
	.update		=	s390_sha_update,
	.final		=	s390_sha_final,
	.export		=	sha256_export,
	.import		=	sha256_import,
	.descsize	=	sizeof(struct s390_sha_ctx),
	.statesize	=	sizeof(struct sha256_state),
	.base		=	{
		.cra_name	=	"sha224",
		.cra_driver_name=	"sha224-s390",
109
		.cra_priority	=	300,
110 111 112 113 114 115 116 117 118
		.cra_blocksize	=	SHA224_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
};

static int __init sha256_s390_init(void)
{
	int ret;

119
	if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA_256))
120
		return -ENODEV;
121 122 123 124 125 126 127 128
	ret = crypto_register_shash(&sha256_alg);
	if (ret < 0)
		goto out;
	ret = crypto_register_shash(&sha224_alg);
	if (ret < 0)
		crypto_unregister_shash(&sha256_alg);
out:
	return ret;
Jan Glauber's avatar
Jan Glauber committed
129 130
}

131
static void __exit sha256_s390_fini(void)
Jan Glauber's avatar
Jan Glauber committed
132
{
133 134
	crypto_unregister_shash(&sha224_alg);
	crypto_unregister_shash(&sha256_alg);
Jan Glauber's avatar
Jan Glauber committed
135 136
}

137
module_cpu_feature_match(MSA, sha256_s390_init);
138
module_exit(sha256_s390_fini);
Jan Glauber's avatar
Jan Glauber committed
139

140 141
MODULE_ALIAS_CRYPTO("sha256");
MODULE_ALIAS_CRYPTO("sha224");
Jan Glauber's avatar
Jan Glauber committed
142
MODULE_LICENSE("GPL");
143
MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm");