1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Cryptographic API. 4 * 5 * s390 implementation of the SHA512 and SHA384 Secure Hash Algorithm. 6 * 7 * Copyright IBM Corp. 2019 8 * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com) 9 */ 10 #include <asm/cpacf.h> 11 #include <crypto/internal/hash.h> 12 #include <crypto/sha3.h> 13 #include <linux/cpufeature.h> 14 #include <linux/errno.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/string.h> 18 19 #include "sha.h" 20 21 static int sha3_512_init(struct shash_desc *desc) 22 { 23 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 24 25 sctx->first_message_part = test_facility(86); 26 if (!sctx->first_message_part) 27 memset(sctx->state, 0, sizeof(sctx->state)); 28 sctx->count = 0; 29 sctx->func = CPACF_KIMD_SHA3_512; 30 31 return 0; 32 } 33 34 static int sha3_512_export(struct shash_desc *desc, void *out) 35 { 36 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 37 union { 38 u8 *u8; 39 u64 *u64; 40 } p = { .u8 = out }; 41 int i; 42 43 if (sctx->first_message_part) { 44 memset(out, 0, SHA3_STATE_SIZE); 45 return 0; 46 } 47 for (i = 0; i < SHA3_STATE_SIZE / 8; i++) 48 put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); 49 return 0; 50 } 51 52 static int sha3_512_import(struct shash_desc *desc, const void *in) 53 { 54 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 55 union { 56 const u8 *u8; 57 const u64 *u64; 58 } p = { .u8 = in }; 59 int i; 60 61 for (i = 0; i < SHA3_STATE_SIZE / 8; i++) 62 sctx->sha3.state[i] = cpu_to_le64(get_unaligned(p.u64++)); 63 sctx->count = 0; 64 sctx->first_message_part = 0; 65 sctx->func = CPACF_KIMD_SHA3_512; 66 67 return 0; 68 } 69 70 static int sha3_384_import(struct shash_desc *desc, const void *in) 71 { 72 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 73 74 sha3_512_import(desc, in); 75 sctx->func = CPACF_KIMD_SHA3_384; 76 return 0; 77 } 78 79 static struct shash_alg sha3_512_alg = { 80 .digestsize = SHA3_512_DIGEST_SIZE, 81 .init = sha3_512_init, 82 .update = s390_sha_update_blocks, 83 .finup = s390_sha_finup, 84 .export = sha3_512_export, 85 .import = sha3_512_import, 86 .descsize = S390_SHA_CTX_SIZE, 87 .statesize = SHA3_STATE_SIZE, 88 .base = { 89 .cra_name = "sha3-512", 90 .cra_driver_name = "sha3-512-s390", 91 .cra_priority = 300, 92 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 93 .cra_blocksize = SHA3_512_BLOCK_SIZE, 94 .cra_module = THIS_MODULE, 95 } 96 }; 97 98 MODULE_ALIAS_CRYPTO("sha3-512"); 99 100 static int sha3_384_init(struct shash_desc *desc) 101 { 102 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 103 104 sha3_512_init(desc); 105 sctx->func = CPACF_KIMD_SHA3_384; 106 return 0; 107 } 108 109 static struct shash_alg sha3_384_alg = { 110 .digestsize = SHA3_384_DIGEST_SIZE, 111 .init = sha3_384_init, 112 .update = s390_sha_update_blocks, 113 .finup = s390_sha_finup, 114 .export = sha3_512_export, /* same as for 512 */ 115 .import = sha3_384_import, /* function code different! */ 116 .descsize = S390_SHA_CTX_SIZE, 117 .statesize = SHA3_STATE_SIZE, 118 .base = { 119 .cra_name = "sha3-384", 120 .cra_driver_name = "sha3-384-s390", 121 .cra_priority = 300, 122 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 123 .cra_blocksize = SHA3_384_BLOCK_SIZE, 124 .cra_ctxsize = sizeof(struct s390_sha_ctx), 125 .cra_module = THIS_MODULE, 126 } 127 }; 128 129 MODULE_ALIAS_CRYPTO("sha3-384"); 130 131 static int __init init(void) 132 { 133 int ret; 134 135 if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512)) 136 return -ENODEV; 137 ret = crypto_register_shash(&sha3_512_alg); 138 if (ret < 0) 139 goto out; 140 ret = crypto_register_shash(&sha3_384_alg); 141 if (ret < 0) 142 crypto_unregister_shash(&sha3_512_alg); 143 out: 144 return ret; 145 } 146 147 static void __exit fini(void) 148 { 149 crypto_unregister_shash(&sha3_512_alg); 150 crypto_unregister_shash(&sha3_384_alg); 151 } 152 153 module_cpu_feature_match(S390_CPU_FEATURE_MSA, init); 154 module_exit(fini); 155 156 MODULE_LICENSE("GPL"); 157 MODULE_DESCRIPTION("SHA3-512 and SHA3-384 Secure Hash Algorithm"); 158