1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Cryptographic API. 4 * 5 * s390 generic implementation of the SHA Secure Hash Algorithms. 6 * 7 * Copyright IBM Corp. 2007 8 * Author(s): Jan Glauber (jang@de.ibm.com) 9 */ 10 11 #include <crypto/internal/hash.h> 12 #include <linux/export.h> 13 #include <linux/module.h> 14 #include <asm/cpacf.h> 15 #include "sha.h" 16 17 int s390_sha_update_blocks(struct shash_desc *desc, const u8 *data, 18 unsigned int len) 19 { 20 unsigned int bsize = crypto_shash_blocksize(desc->tfm); 21 struct s390_sha_ctx *ctx = shash_desc_ctx(desc); 22 unsigned int n; 23 int fc; 24 25 fc = ctx->func; 26 if (ctx->first_message_part) 27 fc |= CPACF_KIMD_NIP; 28 29 /* process as many blocks as possible */ 30 n = (len / bsize) * bsize; 31 ctx->count += n; 32 switch (ctx->func) { 33 case CPACF_KLMD_SHA_512: 34 case CPACF_KLMD_SHA3_384: 35 if (ctx->count < n) 36 ctx->sha512.count_hi++; 37 break; 38 } 39 cpacf_kimd(fc, ctx->state, data, n); 40 ctx->first_message_part = 0; 41 return len - n; 42 } 43 EXPORT_SYMBOL_GPL(s390_sha_update_blocks); 44 45 static int s390_crypto_shash_parmsize(int func) 46 { 47 switch (func) { 48 case CPACF_KLMD_SHA_1: 49 return 20; 50 case CPACF_KLMD_SHA_256: 51 return 32; 52 case CPACF_KLMD_SHA_512: 53 return 64; 54 case CPACF_KLMD_SHA3_224: 55 case CPACF_KLMD_SHA3_256: 56 case CPACF_KLMD_SHA3_384: 57 case CPACF_KLMD_SHA3_512: 58 return 200; 59 default: 60 return -EINVAL; 61 } 62 } 63 64 int s390_sha_finup(struct shash_desc *desc, const u8 *src, unsigned int len, 65 u8 *out) 66 { 67 struct s390_sha_ctx *ctx = shash_desc_ctx(desc); 68 int mbl_offset, fc; 69 u64 bits; 70 71 ctx->count += len; 72 73 bits = ctx->count * 8; 74 mbl_offset = s390_crypto_shash_parmsize(ctx->func); 75 if (mbl_offset < 0) 76 return -EINVAL; 77 78 mbl_offset = mbl_offset / sizeof(u32); 79 80 /* set total msg bit length (mbl) in CPACF parmblock */ 81 switch (ctx->func) { 82 case CPACF_KLMD_SHA_512: 83 /* The SHA512 parmblock has a 128-bit mbl field. */ 84 if (ctx->count < len) 85 ctx->sha512.count_hi++; 86 ctx->sha512.count_hi <<= 3; 87 ctx->sha512.count_hi |= ctx->count >> 61; 88 mbl_offset += sizeof(u64) / sizeof(u32); 89 fallthrough; 90 case CPACF_KLMD_SHA_1: 91 case CPACF_KLMD_SHA_256: 92 memcpy(ctx->state + mbl_offset, &bits, sizeof(bits)); 93 break; 94 case CPACF_KLMD_SHA3_224: 95 case CPACF_KLMD_SHA3_256: 96 case CPACF_KLMD_SHA3_384: 97 case CPACF_KLMD_SHA3_512: 98 break; 99 default: 100 return -EINVAL; 101 } 102 103 fc = ctx->func; 104 fc |= test_facility(86) ? CPACF_KLMD_DUFOP : 0; 105 if (ctx->first_message_part) 106 fc |= CPACF_KLMD_NIP; 107 cpacf_klmd(fc, ctx->state, src, len); 108 109 /* copy digest to out */ 110 memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); 111 112 return 0; 113 } 114 EXPORT_SYMBOL_GPL(s390_sha_finup); 115 116 MODULE_LICENSE("GPL"); 117 MODULE_DESCRIPTION("s390 SHA cipher common functions"); 118