162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Cryptographic API. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * s390 Version: 862306a36Sopenharmony_ci * Copyright IBM Corp. 2005, 2011 962306a36Sopenharmony_ci * Author(s): Jan Glauber (jang@de.ibm.com) 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#include <crypto/internal/hash.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/cpufeature.h> 1562306a36Sopenharmony_ci#include <crypto/sha2.h> 1662306a36Sopenharmony_ci#include <asm/cpacf.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "sha.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic int s390_sha256_init(struct shash_desc *desc) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci sctx->state[0] = SHA256_H0; 2562306a36Sopenharmony_ci sctx->state[1] = SHA256_H1; 2662306a36Sopenharmony_ci sctx->state[2] = SHA256_H2; 2762306a36Sopenharmony_ci sctx->state[3] = SHA256_H3; 2862306a36Sopenharmony_ci sctx->state[4] = SHA256_H4; 2962306a36Sopenharmony_ci sctx->state[5] = SHA256_H5; 3062306a36Sopenharmony_ci sctx->state[6] = SHA256_H6; 3162306a36Sopenharmony_ci sctx->state[7] = SHA256_H7; 3262306a36Sopenharmony_ci sctx->count = 0; 3362306a36Sopenharmony_ci sctx->func = CPACF_KIMD_SHA_256; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci return 0; 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic int sha256_export(struct shash_desc *desc, void *out) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 4162306a36Sopenharmony_ci struct sha256_state *octx = out; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci octx->count = sctx->count; 4462306a36Sopenharmony_ci memcpy(octx->state, sctx->state, sizeof(octx->state)); 4562306a36Sopenharmony_ci memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); 4662306a36Sopenharmony_ci return 0; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic int sha256_import(struct shash_desc *desc, const void *in) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 5262306a36Sopenharmony_ci const struct sha256_state *ictx = in; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci sctx->count = ictx->count; 5562306a36Sopenharmony_ci memcpy(sctx->state, ictx->state, sizeof(ictx->state)); 5662306a36Sopenharmony_ci memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 5762306a36Sopenharmony_ci sctx->func = CPACF_KIMD_SHA_256; 5862306a36Sopenharmony_ci return 0; 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic struct shash_alg sha256_alg = { 6262306a36Sopenharmony_ci .digestsize = SHA256_DIGEST_SIZE, 6362306a36Sopenharmony_ci .init = s390_sha256_init, 6462306a36Sopenharmony_ci .update = s390_sha_update, 6562306a36Sopenharmony_ci .final = s390_sha_final, 6662306a36Sopenharmony_ci .export = sha256_export, 6762306a36Sopenharmony_ci .import = sha256_import, 6862306a36Sopenharmony_ci .descsize = sizeof(struct s390_sha_ctx), 6962306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 7062306a36Sopenharmony_ci .base = { 7162306a36Sopenharmony_ci .cra_name = "sha256", 7262306a36Sopenharmony_ci .cra_driver_name= "sha256-s390", 7362306a36Sopenharmony_ci .cra_priority = 300, 7462306a36Sopenharmony_ci .cra_blocksize = SHA256_BLOCK_SIZE, 7562306a36Sopenharmony_ci .cra_module = THIS_MODULE, 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int s390_sha224_init(struct shash_desc *desc) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci sctx->state[0] = SHA224_H0; 8462306a36Sopenharmony_ci sctx->state[1] = SHA224_H1; 8562306a36Sopenharmony_ci sctx->state[2] = SHA224_H2; 8662306a36Sopenharmony_ci sctx->state[3] = SHA224_H3; 8762306a36Sopenharmony_ci sctx->state[4] = SHA224_H4; 8862306a36Sopenharmony_ci sctx->state[5] = SHA224_H5; 8962306a36Sopenharmony_ci sctx->state[6] = SHA224_H6; 9062306a36Sopenharmony_ci sctx->state[7] = SHA224_H7; 9162306a36Sopenharmony_ci sctx->count = 0; 9262306a36Sopenharmony_ci sctx->func = CPACF_KIMD_SHA_256; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci return 0; 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic struct shash_alg sha224_alg = { 9862306a36Sopenharmony_ci .digestsize = SHA224_DIGEST_SIZE, 9962306a36Sopenharmony_ci .init = s390_sha224_init, 10062306a36Sopenharmony_ci .update = s390_sha_update, 10162306a36Sopenharmony_ci .final = s390_sha_final, 10262306a36Sopenharmony_ci .export = sha256_export, 10362306a36Sopenharmony_ci .import = sha256_import, 10462306a36Sopenharmony_ci .descsize = sizeof(struct s390_sha_ctx), 10562306a36Sopenharmony_ci .statesize = sizeof(struct sha256_state), 10662306a36Sopenharmony_ci .base = { 10762306a36Sopenharmony_ci .cra_name = "sha224", 10862306a36Sopenharmony_ci .cra_driver_name= "sha224-s390", 10962306a36Sopenharmony_ci .cra_priority = 300, 11062306a36Sopenharmony_ci .cra_blocksize = SHA224_BLOCK_SIZE, 11162306a36Sopenharmony_ci .cra_module = THIS_MODULE, 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic int __init sha256_s390_init(void) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci int ret; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA_256)) 12062306a36Sopenharmony_ci return -ENODEV; 12162306a36Sopenharmony_ci ret = crypto_register_shash(&sha256_alg); 12262306a36Sopenharmony_ci if (ret < 0) 12362306a36Sopenharmony_ci goto out; 12462306a36Sopenharmony_ci ret = crypto_register_shash(&sha224_alg); 12562306a36Sopenharmony_ci if (ret < 0) 12662306a36Sopenharmony_ci crypto_unregister_shash(&sha256_alg); 12762306a36Sopenharmony_ciout: 12862306a36Sopenharmony_ci return ret; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic void __exit sha256_s390_fini(void) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci crypto_unregister_shash(&sha224_alg); 13462306a36Sopenharmony_ci crypto_unregister_shash(&sha256_alg); 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cimodule_cpu_feature_match(S390_CPU_FEATURE_MSA, sha256_s390_init); 13862306a36Sopenharmony_cimodule_exit(sha256_s390_fini); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("sha256"); 14162306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("sha224"); 14262306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 14362306a36Sopenharmony_ciMODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm"); 144