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 <crypto/internal/hash.h> 11 #include <linux/init.h> 12 #include <linux/module.h> 13 #include <linux/cpufeature.h> 14 #include <crypto/sha.h> 15 #include <crypto/sha3.h> 16 #include <asm/cpacf.h> 17 18 #include "sha.h" 19 20 static int sha3_512_init(struct shash_desc *desc) 21 { 22 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 23 24 memset(sctx->state, 0, sizeof(sctx->state)); 25 sctx->count = 0; 26 sctx->func = CPACF_KIMD_SHA3_512; 27 28 return 0; 29 } 30 31 static int sha3_512_export(struct shash_desc *desc, void *out) 32 { 33 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 34 struct sha3_state *octx = out; 35 36 octx->rsiz = sctx->count; 37 octx->rsizw = sctx->count >> 32; 38 39 memcpy(octx->st, sctx->state, sizeof(octx->st)); 40 memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); 41 42 return 0; 43 } 44 45 static int sha3_512_import(struct shash_desc *desc, const void *in) 46 { 47 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 48 const struct sha3_state *ictx = in; 49 50 if (unlikely(ictx->rsizw)) 51 return -ERANGE; 52 sctx->count = ictx->rsiz; 53 54 memcpy(sctx->state, ictx->st, sizeof(ictx->st)); 55 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 56 sctx->func = CPACF_KIMD_SHA3_512; 57 58 return 0; 59 } 60 61 static int sha3_384_import(struct shash_desc *desc, const void *in) 62 { 63 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 64 const struct sha3_state *ictx = in; 65 66 if (unlikely(ictx->rsizw)) 67 return -ERANGE; 68 sctx->count = ictx->rsiz; 69 70 memcpy(sctx->state, ictx->st, sizeof(ictx->st)); 71 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); 72 sctx->func = CPACF_KIMD_SHA3_384; 73 74 return 0; 75 } 76 77 static struct shash_alg sha3_512_alg = { 78 .digestsize = SHA3_512_DIGEST_SIZE, 79 .init = sha3_512_init, 80 .update = s390_sha_update, 81 .final = s390_sha_final, 82 .export = sha3_512_export, 83 .import = sha3_512_import, 84 .descsize = sizeof(struct s390_sha_ctx), 85 .statesize = sizeof(struct sha3_state), 86 .base = { 87 .cra_name = "sha3-512", 88 .cra_driver_name = "sha3-512-s390", 89 .cra_priority = 300, 90 .cra_blocksize = SHA3_512_BLOCK_SIZE, 91 .cra_module = THIS_MODULE, 92 } 93 }; 94 95 MODULE_ALIAS_CRYPTO("sha3-512"); 96 97 static int sha3_384_init(struct shash_desc *desc) 98 { 99 struct s390_sha_ctx *sctx = shash_desc_ctx(desc); 100 101 memset(sctx->state, 0, sizeof(sctx->state)); 102 sctx->count = 0; 103 sctx->func = CPACF_KIMD_SHA3_384; 104 105 return 0; 106 } 107 108 static struct shash_alg sha3_384_alg = { 109 .digestsize = SHA3_384_DIGEST_SIZE, 110 .init = sha3_384_init, 111 .update = s390_sha_update, 112 .final = s390_sha_final, 113 .export = sha3_512_export, /* same as for 512 */ 114 .import = sha3_384_import, /* function code different! */ 115 .descsize = sizeof(struct s390_sha_ctx), 116 .statesize = sizeof(struct sha3_state), 117 .base = { 118 .cra_name = "sha3-384", 119 .cra_driver_name = "sha3-384-s390", 120 .cra_priority = 300, 121 .cra_blocksize = SHA3_384_BLOCK_SIZE, 122 .cra_ctxsize = sizeof(struct s390_sha_ctx), 123 .cra_module = THIS_MODULE, 124 } 125 }; 126 127 MODULE_ALIAS_CRYPTO("sha3-384"); 128 129 static int __init init(void) 130 { 131 int ret; 132 133 if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512)) 134 return -ENODEV; 135 ret = crypto_register_shash(&sha3_512_alg); 136 if (ret < 0) 137 goto out; 138 ret = crypto_register_shash(&sha3_384_alg); 139 if (ret < 0) 140 crypto_unregister_shash(&sha3_512_alg); 141 out: 142 return ret; 143 } 144 145 static void __exit fini(void) 146 { 147 crypto_unregister_shash(&sha3_512_alg); 148 crypto_unregister_shash(&sha3_384_alg); 149 } 150 151 module_cpu_feature_match(MSA, init); 152 module_exit(fini); 153 154 MODULE_LICENSE("GPL"); 155 MODULE_DESCRIPTION("SHA3-512 and SHA3-384 Secure Hash Algorithm"); 156