1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Cryptographic API. 4 * 5 * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm. 6 * 7 * s390 Version: 8 * Copyright IBM Corp. 2005, 2011 9 * Author(s): Jan Glauber (jang@de.ibm.com) 10 */ 11 #include <crypto/internal/hash.h> 12 #include <linux/init.h> 13 #include <linux/module.h> 14 #include <linux/cpufeature.h> 15 #include <crypto/sha2.h> 16 #include <asm/cpacf.h> 17 18 #include "sha.h" 19 20 static int s390_sha256_init(struct shash_desc *desc) 21 { 22 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 23 24 sctx->state[0] = SHA256_H0; 25 sctx->state[1] = SHA256_H1; 26 sctx->state[2] = SHA256_H2; 27 sctx->state[3] = SHA256_H3; 28 sctx->state[4] = SHA256_H4; 29 sctx->state[5] = SHA256_H5; 30 sctx->state[6] = SHA256_H6; 31 sctx->state[7] = SHA256_H7; 32 sctx->count = 0; 33 sctx->func = CPACF_KIMD_SHA_256; 34 35 return 0; 36 } 37 38 static int sha256_export(struct shash_desc *desc, void *out) 39 { 40 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 41 struct sha256_state *octx = out; 42 43 octx->count = sctx->count; 44 memcpy(octx->state, sctx->state, sizeof(octx->state)); 45 memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); 46 return 0; 47 } 48 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 sctx->count = ictx->count; 55 memcpy(sctx->state, ictx->state, sizeof(ictx->state)); 56 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 57 sctx->func = CPACF_KIMD_SHA_256; 58 return 0; 59 } 60 61 static struct shash_alg sha256_alg = { 62 .digestsize = SHA256_DIGEST_SIZE, 63 .init = s390_sha256_init, 64 .update = s390_sha_update, 65 .final = s390_sha_final, 66 .export = sha256_export, 67 .import = sha256_import, 68 .descsize = sizeof(struct s390_sha_ctx), 69 .statesize = sizeof(struct sha256_state), 70 .base = { 71 .cra_name = "sha256", 72 .cra_driver_name= "sha256-s390", 73 .cra_priority = 300, 74 .cra_blocksize = SHA256_BLOCK_SIZE, 75 .cra_module = THIS_MODULE, 76 } 77 }; 78 79 static int s390_sha224_init(struct shash_desc *desc) 80 { 81 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 82 83 sctx->state[0] = SHA224_H0; 84 sctx->state[1] = SHA224_H1; 85 sctx->state[2] = SHA224_H2; 86 sctx->state[3] = SHA224_H3; 87 sctx->state[4] = SHA224_H4; 88 sctx->state[5] = SHA224_H5; 89 sctx->state[6] = SHA224_H6; 90 sctx->state[7] = SHA224_H7; 91 sctx->count = 0; 92 sctx->func = CPACF_KIMD_SHA_256; 93 94 return 0; 95 } 96 97 static struct shash_alg sha224_alg = { 98 .digestsize = SHA224_DIGEST_SIZE, 99 .init = s390_sha224_init, 100 .update = s390_sha_update, 101 .final = s390_sha_final, 102 .export = sha256_export, 103 .import = sha256_import, 104 .descsize = sizeof(struct s390_sha_ctx), 105 .statesize = sizeof(struct sha256_state), 106 .base = { 107 .cra_name = "sha224", 108 .cra_driver_name= "sha224-s390", 109 .cra_priority = 300, 110 .cra_blocksize = SHA224_BLOCK_SIZE, 111 .cra_module = THIS_MODULE, 112 } 113 }; 114 115 static int __init sha256_s390_init(void) 116 { 117 int ret; 118 119 if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA_256)) 120 return -ENODEV; 121 ret = crypto_register_shash(&sha256_alg); 122 if (ret < 0) 123 goto out; 124 ret = crypto_register_shash(&sha224_alg); 125 if (ret < 0) 126 crypto_unregister_shash(&sha256_alg); 127 out: 128 return ret; 129 } 130 131 static void __exit sha256_s390_fini(void) 132 { 133 crypto_unregister_shash(&sha224_alg); 134 crypto_unregister_shash(&sha256_alg); 135 } 136 137 module_cpu_feature_match(MSA, sha256_s390_init); 138 module_exit(sha256_s390_fini); 139 140 MODULE_ALIAS_CRYPTO("sha256"); 141 MODULE_ALIAS_CRYPTO("sha224"); 142 MODULE_LICENSE("GPL"); 143 MODULE_DESCRIPTION("SHA256 and SHA224 Secure Hash Algorithm"); 144