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. 2019 9 * Author(s): Joerg Schmidbauer (jschmidb@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/sha.h> 16 #include <crypto/sha3.h> 17 #include <asm/cpacf.h> 18 19 #include "sha.h" 20 21 static int sha3_256_init(struct shash_desc *desc) 22 { 23 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 24 25 memset(sctx->state, 0, sizeof(sctx->state)); 26 sctx->count = 0; 27 sctx->func = CPACF_KIMD_SHA3_256; 28 29 return 0; 30 } 31 32 static int sha3_256_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 memcpy(octx->st, sctx->state, sizeof(octx->st)); 39 memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); 40 41 return 0; 42 } 43 44 static int sha3_256_import(struct shash_desc *desc, const void *in) 45 { 46 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 47 const struct sha3_state *ictx = in; 48 49 sctx->count = ictx->rsiz; 50 memcpy(sctx->state, ictx->st, sizeof(ictx->st)); 51 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 52 sctx->func = CPACF_KIMD_SHA3_256; 53 54 return 0; 55 } 56 57 static int sha3_224_import(struct shash_desc *desc, const void *in) 58 { 59 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 60 const struct sha3_state *ictx = in; 61 62 sctx->count = ictx->rsiz; 63 memcpy(sctx->state, ictx->st, sizeof(ictx->st)); 64 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 65 sctx->func = CPACF_KIMD_SHA3_224; 66 67 return 0; 68 } 69 70 static struct shash_alg sha3_256_alg = { 71 .digestsize = SHA3_256_DIGEST_SIZE, /* = 32 */ 72 .init = sha3_256_init, 73 .update = s390_sha_update, 74 .final = s390_sha_final, 75 .export = sha3_256_export, 76 .import = sha3_256_import, 77 .descsize = sizeof(struct s390_sha_ctx), 78 .statesize = sizeof(struct sha3_state), 79 .base = { 80 .cra_name = "sha3-256", 81 .cra_driver_name = "sha3-256-s390", 82 .cra_priority = 300, 83 .cra_blocksize = SHA3_256_BLOCK_SIZE, 84 .cra_module = THIS_MODULE, 85 } 86 }; 87 88 static int sha3_224_init(struct shash_desc *desc) 89 { 90 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 91 92 memset(sctx->state, 0, sizeof(sctx->state)); 93 sctx->count = 0; 94 sctx->func = CPACF_KIMD_SHA3_224; 95 96 return 0; 97 } 98 99 static struct shash_alg sha3_224_alg = { 100 .digestsize = SHA3_224_DIGEST_SIZE, 101 .init = sha3_224_init, 102 .update = s390_sha_update, 103 .final = s390_sha_final, 104 .export = sha3_256_export, /* same as for 256 */ 105 .import = sha3_224_import, /* function code different! */ 106 .descsize = sizeof(struct s390_sha_ctx), 107 .statesize = sizeof(struct sha3_state), 108 .base = { 109 .cra_name = "sha3-224", 110 .cra_driver_name = "sha3-224-s390", 111 .cra_priority = 300, 112 .cra_blocksize = SHA3_224_BLOCK_SIZE, 113 .cra_module = THIS_MODULE, 114 } 115 }; 116 117 static int __init sha3_256_s390_init(void) 118 { 119 int ret; 120 121 if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256)) 122 return -ENODEV; 123 124 ret = crypto_register_shash(&sha3_256_alg); 125 if (ret < 0) 126 goto out; 127 128 ret = crypto_register_shash(&sha3_224_alg); 129 if (ret < 0) 130 crypto_unregister_shash(&sha3_256_alg); 131 out: 132 return ret; 133 } 134 135 static void __exit sha3_256_s390_fini(void) 136 { 137 crypto_unregister_shash(&sha3_224_alg); 138 crypto_unregister_shash(&sha3_256_alg); 139 } 140 141 module_cpu_feature_match(MSA, sha3_256_s390_init); 142 module_exit(sha3_256_s390_fini); 143 144 MODULE_ALIAS_CRYPTO("sha3-256"); 145 MODULE_ALIAS_CRYPTO("sha3-224"); 146 MODULE_LICENSE("GPL"); 147 MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm"); 148