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