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 union { 39 u8 *u8; 40 u64 *u64; 41 } p = { .u8 = out }; 42 int i; 43 44 if (sctx->first_message_part) { 45 memset(out, 0, SHA3_STATE_SIZE); 46 return 0; 47 } 48 for (i = 0; i < SHA3_STATE_SIZE / 8; i++) 49 put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); 50 return 0; 51 } 52 53 static int sha3_256_import(struct shash_desc *desc, const void *in) 54 { 55 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 56 union { 57 const u8 *u8; 58 const u64 *u64; 59 } p = { .u8 = in }; 60 int i; 61 62 for (i = 0; i < SHA3_STATE_SIZE / 8; i++) 63 sctx->sha3.state[i] = cpu_to_le64(get_unaligned(p.u64++)); 64 sctx->count = 0; 65 sctx->first_message_part = 0; 66 sctx->func = CPACF_KIMD_SHA3_256; 67 68 return 0; 69 } 70 71 static int sha3_224_import(struct shash_desc *desc, const void *in) 72 { 73 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 74 75 sha3_256_import(desc, in); 76 sctx->func = CPACF_KIMD_SHA3_224; 77 return 0; 78 } 79 80 static struct shash_alg sha3_256_alg = { 81 .digestsize = SHA3_256_DIGEST_SIZE, /* = 32 */ 82 .init = sha3_256_init, 83 .update = s390_sha_update_blocks, 84 .finup = s390_sha_finup, 85 .export = sha3_256_export, 86 .import = sha3_256_import, 87 .descsize = S390_SHA_CTX_SIZE, 88 .statesize = SHA3_STATE_SIZE, 89 .base = { 90 .cra_name = "sha3-256", 91 .cra_driver_name = "sha3-256-s390", 92 .cra_priority = 300, 93 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 94 .cra_blocksize = SHA3_256_BLOCK_SIZE, 95 .cra_module = THIS_MODULE, 96 } 97 }; 98 99 static int sha3_224_init(struct shash_desc *desc) 100 { 101 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 102 103 sha3_256_init(desc); 104 sctx->func = CPACF_KIMD_SHA3_224; 105 return 0; 106 } 107 108 static struct shash_alg sha3_224_alg = { 109 .digestsize = SHA3_224_DIGEST_SIZE, 110 .init = sha3_224_init, 111 .update = s390_sha_update_blocks, 112 .finup = s390_sha_finup, 113 .export = sha3_256_export, /* same as for 256 */ 114 .import = sha3_224_import, /* function code different! */ 115 .descsize = S390_SHA_CTX_SIZE, 116 .statesize = SHA3_STATE_SIZE, 117 .base = { 118 .cra_name = "sha3-224", 119 .cra_driver_name = "sha3-224-s390", 120 .cra_priority = 300, 121 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 122 .cra_blocksize = SHA3_224_BLOCK_SIZE, 123 .cra_module = THIS_MODULE, 124 } 125 }; 126 127 static int __init sha3_256_s390_init(void) 128 { 129 int ret; 130 131 if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256)) 132 return -ENODEV; 133 134 ret = crypto_register_shash(&sha3_256_alg); 135 if (ret < 0) 136 goto out; 137 138 ret = crypto_register_shash(&sha3_224_alg); 139 if (ret < 0) 140 crypto_unregister_shash(&sha3_256_alg); 141 out: 142 return ret; 143 } 144 145 static void __exit sha3_256_s390_fini(void) 146 { 147 crypto_unregister_shash(&sha3_224_alg); 148 crypto_unregister_shash(&sha3_256_alg); 149 } 150 151 module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha3_256_s390_init); 152 module_exit(sha3_256_s390_fini); 153 154 MODULE_ALIAS_CRYPTO("sha3-256"); 155 MODULE_ALIAS_CRYPTO("sha3-224"); 156 MODULE_LICENSE("GPL"); 157 MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm"); 158