Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[CRYPTO] sha512: Hardware acceleration for s390

Exploit the System z10 hardware acceleration for SHA512.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Jan Glauber and committed by
Herbert Xu
291dc7c0 604973f1

+97 -4
+1
arch/s390/crypto/Makefile
··· 4 4 5 5 obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o 6 6 obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o 7 + obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o 7 8 obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o 8 9 obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o 9 10 obj-$(CONFIG_S390_PRNG) += prng.o
+2
arch/s390/crypto/crypt_s390.h
··· 82 82 KIMD_QUERY = CRYPT_S390_KIMD | 0, 83 83 KIMD_SHA_1 = CRYPT_S390_KIMD | 1, 84 84 KIMD_SHA_256 = CRYPT_S390_KIMD | 2, 85 + KIMD_SHA_512 = CRYPT_S390_KIMD | 3, 85 86 }; 86 87 87 88 /* ··· 93 92 KLMD_QUERY = CRYPT_S390_KLMD | 0, 94 93 KLMD_SHA_1 = CRYPT_S390_KLMD | 1, 95 94 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 95 + KLMD_SHA_512 = CRYPT_S390_KLMD | 3, 96 96 }; 97 97 98 98 /*
+3 -2
arch/s390/crypto/sha.h
··· 19 19 #include <crypto/sha.h> 20 20 21 21 /* must be big enough for the largest SHA variant */ 22 - #define SHA_MAX_BLOCK_SIZE SHA256_BLOCK_SIZE 22 + #define SHA_MAX_STATE_SIZE 16 23 + #define SHA_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE 23 24 24 25 struct s390_sha_ctx { 25 26 u64 count; /* message length in bytes */ 26 - u32 state[8]; 27 + u32 state[SHA_MAX_STATE_SIZE]; 27 28 u8 buf[2 * SHA_MAX_BLOCK_SIZE]; 28 29 int func; /* KIMD function to use */ 29 30 };
+71
arch/s390/crypto/sha512_s390.c
··· 1 + /* 2 + * Cryptographic API. 3 + * 4 + * s390 implementation of the SHA512 Secure Hash Algorithm. 5 + * 6 + * Copyright IBM Corp. 2007 7 + * Author(s): Jan Glauber (jang@de.ibm.com) 8 + * 9 + * This program is free software; you can redistribute it and/or modify it 10 + * under the terms of the GNU General Public License as published by the Free 11 + * Software Foundation; either version 2 of the License, or (at your option) 12 + * any later version. 13 + * 14 + */ 15 + #include <linux/init.h> 16 + #include <linux/module.h> 17 + #include <linux/crypto.h> 18 + 19 + #include "sha.h" 20 + #include "crypt_s390.h" 21 + 22 + static void sha512_init(struct crypto_tfm *tfm) 23 + { 24 + struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); 25 + 26 + *(__u64 *)&ctx->state[0] = 0x6a09e667f3bcc908ULL; 27 + *(__u64 *)&ctx->state[2] = 0xbb67ae8584caa73bULL; 28 + *(__u64 *)&ctx->state[4] = 0x3c6ef372fe94f82bULL; 29 + *(__u64 *)&ctx->state[6] = 0xa54ff53a5f1d36f1ULL; 30 + *(__u64 *)&ctx->state[8] = 0x510e527fade682d1ULL; 31 + *(__u64 *)&ctx->state[10] = 0x9b05688c2b3e6c1fULL; 32 + *(__u64 *)&ctx->state[12] = 0x1f83d9abfb41bd6bULL; 33 + *(__u64 *)&ctx->state[14] = 0x5be0cd19137e2179ULL; 34 + ctx->count = 0; 35 + ctx->func = KIMD_SHA_512; 36 + } 37 + 38 + static struct crypto_alg alg = { 39 + .cra_name = "sha512", 40 + .cra_driver_name = "sha512-s390", 41 + .cra_priority = CRYPT_S390_PRIORITY, 42 + .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 43 + .cra_blocksize = SHA512_BLOCK_SIZE, 44 + .cra_ctxsize = sizeof(struct s390_sha_ctx), 45 + .cra_module = THIS_MODULE, 46 + .cra_list = LIST_HEAD_INIT(alg.cra_list), 47 + .cra_u = { .digest = { 48 + .dia_digestsize = SHA512_DIGEST_SIZE, 49 + .dia_init = sha512_init, 50 + .dia_update = s390_sha_update, 51 + .dia_final = s390_sha_final } } 52 + }; 53 + 54 + static int __init init(void) 55 + { 56 + if (!crypt_s390_func_available(KIMD_SHA_512)) 57 + return -EOPNOTSUPP; 58 + return crypto_register_alg(&alg); 59 + } 60 + 61 + static void __exit fini(void) 62 + { 63 + crypto_unregister_alg(&alg); 64 + } 65 + 66 + module_init(init); 67 + module_exit(fini); 68 + 69 + MODULE_ALIAS("sha512"); 70 + MODULE_LICENSE("GPL"); 71 + MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm");
+9 -2
arch/s390/crypto/sha_common.c
··· 59 59 struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); 60 60 unsigned int bsize = crypto_tfm_alg_blocksize(tfm); 61 61 u64 bits; 62 - unsigned int index, end; 62 + unsigned int index, end, plen; 63 63 int ret; 64 + 65 + /* SHA-512 uses 128 bit padding length */ 66 + plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8; 64 67 65 68 /* must perform manual padding */ 66 69 index = ctx->count & (bsize - 1); 67 - end = (index < bsize - 8) ? bsize : (2 * bsize); 70 + end = (index < bsize - plen) ? bsize : (2 * bsize); 68 71 69 72 /* start pad with 1 */ 70 73 ctx->buf[index] = 0x80; ··· 76 73 /* pad with zeros */ 77 74 memset(ctx->buf + index, 0x00, end - index - 8); 78 75 76 + /* 77 + * Append message length. Well, SHA-512 wants a 128 bit lenght value, 78 + * nevertheless we use u64, should be enough for now... 79 + */ 79 80 bits = ctx->count * 8; 80 81 memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); 81 82
+11
drivers/crypto/Kconfig
··· 101 101 This version of SHA implements a 256 bit hash with 128 bits of 102 102 security against collision attacks. 103 103 104 + config CRYPTO_SHA512_S390 105 + tristate "SHA512 digest algorithm" 106 + depends on S390 107 + select CRYPTO_ALGAPI 108 + help 109 + This is the s390 hardware accelerated implementation of the 110 + SHA512 secure hash standard. 111 + 112 + This version of SHA implements a 512 bit hash with 256 bits of 113 + security against collision attacks. 114 + 104 115 config CRYPTO_DES_S390 105 116 tristate "DES and Triple DES cipher algorithms" 106 117 depends on S390