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 <asm/cpacf.h> 12 #include <crypto/internal/hash.h> 13 #include <crypto/sha3.h> 14 #include <linux/cpufeature.h> 15 #include <linux/errno.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/string.h> 19 20 #include "sha.h" 21 22 static int sha3_256_init(struct shash_desc *desc) 23 { 24 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 25 26 sctx->first_message_part = test_facility(86); 27 if (!sctx->first_message_part) 28 memset(sctx->state, 0, sizeof(sctx->state)); 29 sctx->count = 0; 30 sctx->func = CPACF_KIMD_SHA3_256; 31 32 return 0; 33 } 34 35 static int sha3_256_export(struct shash_desc *desc, void *out) 36 { 37 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 38 struct sha3_state *octx = out; 39 40 if (sctx->first_message_part) { 41 memset(sctx->state, 0, sizeof(sctx->state)); 42 sctx->first_message_part = 0; 43 } 44 memcpy(octx->st, sctx->state, sizeof(octx->st)); 45 return 0; 46 } 47 48 static int sha3_256_import(struct shash_desc *desc, const void *in) 49 { 50 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 51 const struct sha3_state *ictx = in; 52 53 sctx->count = 0; 54 memcpy(sctx->state, ictx->st, sizeof(ictx->st)); 55 sctx->first_message_part = 0; 56 sctx->func = CPACF_KIMD_SHA3_256; 57 58 return 0; 59 } 60 61 static int sha3_224_import(struct shash_desc *desc, const void *in) 62 { 63 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 64 65 sha3_256_import(desc, in); 66 sctx->func = CPACF_KIMD_SHA3_224; 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_blocks, 74 .finup = s390_sha_finup, 75 .export = sha3_256_export, 76 .import = sha3_256_import, 77 .descsize = S390_SHA_CTX_SIZE, 78 .statesize = SHA3_STATE_SIZE, 79 .base = { 80 .cra_name = "sha3-256", 81 .cra_driver_name = "sha3-256-s390", 82 .cra_priority = 300, 83 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 84 .cra_blocksize = SHA3_256_BLOCK_SIZE, 85 .cra_module = THIS_MODULE, 86 } 87 }; 88 89 static int sha3_224_init(struct shash_desc *desc) 90 { 91 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 92 93 sha3_256_init(desc); 94 sctx->func = CPACF_KIMD_SHA3_224; 95 return 0; 96 } 97 98 static struct shash_alg sha3_224_alg = { 99 .digestsize = SHA3_224_DIGEST_SIZE, 100 .init = sha3_224_init, 101 .update = s390_sha_update_blocks, 102 .finup = s390_sha_finup, 103 .export = sha3_256_export, /* same as for 256 */ 104 .import = sha3_224_import, /* function code different! */ 105 .descsize = S390_SHA_CTX_SIZE, 106 .statesize = SHA3_STATE_SIZE, 107 .base = { 108 .cra_name = "sha3-224", 109 .cra_driver_name = "sha3-224-s390", 110 .cra_priority = 300, 111 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 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(S390_CPU_FEATURE_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