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