Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Cryptographic API.
  4 *
  5 * s390 implementation of the SHA512 and SHA384 Secure Hash Algorithm.
  6 *
  7 * Copyright IBM Corp. 2019
  8 * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com)
  9 */
 10#include <crypto/internal/hash.h>
 11#include <linux/init.h>
 12#include <linux/module.h>
 13#include <linux/cpufeature.h>
 14#include <crypto/sha3.h>
 15#include <asm/cpacf.h>
 16
 17#include "sha.h"
 18
 19static int sha3_512_init(struct shash_desc *desc)
 20{
 21	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 22
 23	if (!test_facility(86)) /* msa 12 */
 24		memset(sctx->state, 0, sizeof(sctx->state));
 25	sctx->count = 0;
 26	sctx->func = CPACF_KIMD_SHA3_512;
 27	sctx->first_message_part = 1;
 28
 29	return 0;
 30}
 31
 32static int sha3_512_export(struct shash_desc *desc, void *out)
 33{
 34	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 35	struct sha3_state *octx = out;
 36
 37	octx->rsiz = sctx->count;
 38	octx->rsizw = sctx->count >> 32;
 39
 40	memcpy(octx->st, sctx->state, sizeof(octx->st));
 41	memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
 42	octx->partial = sctx->first_message_part;
 43
 44	return 0;
 45}
 46
 47static int sha3_512_import(struct shash_desc *desc, const void *in)
 48{
 49	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 50	const struct sha3_state *ictx = in;
 51
 52	if (unlikely(ictx->rsizw))
 53		return -ERANGE;
 54	sctx->count = ictx->rsiz;
 55
 56	memcpy(sctx->state, ictx->st, sizeof(ictx->st));
 57	memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
 58	sctx->first_message_part = ictx->partial;
 59	sctx->func = CPACF_KIMD_SHA3_512;
 60
 61	return 0;
 62}
 63
 64static int sha3_384_import(struct shash_desc *desc, const void *in)
 65{
 66	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
 67	const struct sha3_state *ictx = in;
 68
 69	if (unlikely(ictx->rsizw))
 70		return -ERANGE;
 71	sctx->count = ictx->rsiz;
 72
 73	memcpy(sctx->state, ictx->st, sizeof(ictx->st));
 74	memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
 75	sctx->first_message_part = ictx->partial;
 76	sctx->func = CPACF_KIMD_SHA3_384;
 77
 78	return 0;
 79}
 80
 81static struct shash_alg sha3_512_alg = {
 82	.digestsize	=	SHA3_512_DIGEST_SIZE,
 83	.init		=	sha3_512_init,
 84	.update		=	s390_sha_update,
 85	.final		=	s390_sha_final,
 86	.export		=	sha3_512_export,
 87	.import		=	sha3_512_import,
 88	.descsize	=	sizeof(struct s390_sha_ctx),
 89	.statesize	=	sizeof(struct sha3_state),
 90	.base		=	{
 91		.cra_name	 =	"sha3-512",
 92		.cra_driver_name =	"sha3-512-s390",
 93		.cra_priority	 =	300,
 94		.cra_blocksize	 =	SHA3_512_BLOCK_SIZE,
 95		.cra_module	 =	THIS_MODULE,
 96	}
 97};
 98
 99MODULE_ALIAS_CRYPTO("sha3-512");
100
101static int sha3_384_init(struct shash_desc *desc)
102{
103	struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
104
105	if (!test_facility(86)) /* msa 12 */
106		memset(sctx->state, 0, sizeof(sctx->state));
107	sctx->count = 0;
108	sctx->func = CPACF_KIMD_SHA3_384;
109	sctx->first_message_part = 1;
110
111	return 0;
112}
113
114static struct shash_alg sha3_384_alg = {
115	.digestsize	=	SHA3_384_DIGEST_SIZE,
116	.init		=	sha3_384_init,
117	.update		=	s390_sha_update,
118	.final		=	s390_sha_final,
119	.export		=	sha3_512_export, /* same as for 512 */
120	.import		=	sha3_384_import, /* function code different! */
121	.descsize	=	sizeof(struct s390_sha_ctx),
122	.statesize	=	sizeof(struct sha3_state),
123	.base		=	{
124		.cra_name	 =	"sha3-384",
125		.cra_driver_name =	"sha3-384-s390",
126		.cra_priority	 =	300,
127		.cra_blocksize	 =	SHA3_384_BLOCK_SIZE,
128		.cra_ctxsize	 =	sizeof(struct s390_sha_ctx),
129		.cra_module	 =	THIS_MODULE,
130	}
131};
132
133MODULE_ALIAS_CRYPTO("sha3-384");
134
135static int __init init(void)
136{
137	int ret;
138
139	if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512))
140		return -ENODEV;
141	ret = crypto_register_shash(&sha3_512_alg);
142	if (ret < 0)
143		goto out;
144	ret = crypto_register_shash(&sha3_384_alg);
145	if (ret < 0)
146		crypto_unregister_shash(&sha3_512_alg);
147out:
148	return ret;
149}
150
151static void __exit fini(void)
152{
153	crypto_unregister_shash(&sha3_512_alg);
154	crypto_unregister_shash(&sha3_384_alg);
155}
156
157module_cpu_feature_match(S390_CPU_FEATURE_MSA, init);
158module_exit(fini);
159
160MODULE_LICENSE("GPL");
161MODULE_DESCRIPTION("SHA3-512 and SHA3-384 Secure Hash Algorithm");