diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/crypto/Makefile | 1 | ||||
-rw-r--r-- | arch/s390/crypto/crypt_s390.h | 2 | ||||
-rw-r--r-- | arch/s390/crypto/sha.h | 5 | ||||
-rw-r--r-- | arch/s390/crypto/sha512_s390.c | 71 | ||||
-rw-r--r-- | arch/s390/crypto/sha_common.c | 11 |
5 files changed, 86 insertions, 4 deletions
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index 5f1a5f89cc9..6a1157fa4f9 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o | 5 | obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o |
6 | obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o | 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 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o | 8 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o |
8 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o | 9 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o |
9 | obj-$(CONFIG_S390_PRNG) += prng.o | 10 | obj-$(CONFIG_S390_PRNG) += prng.o |
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 95f5160df27..9992f95ef99 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h | |||
@@ -82,6 +82,7 @@ enum crypt_s390_kimd_func { | |||
82 | KIMD_QUERY = CRYPT_S390_KIMD | 0, | 82 | KIMD_QUERY = CRYPT_S390_KIMD | 0, |
83 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, | 83 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, |
84 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, | 84 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, |
85 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | /* | 88 | /* |
@@ -92,6 +93,7 @@ enum crypt_s390_klmd_func { | |||
92 | KLMD_QUERY = CRYPT_S390_KLMD | 0, | 93 | KLMD_QUERY = CRYPT_S390_KLMD | 0, |
93 | KLMD_SHA_1 = CRYPT_S390_KLMD | 1, | 94 | KLMD_SHA_1 = CRYPT_S390_KLMD | 1, |
94 | KLMD_SHA_256 = CRYPT_S390_KLMD | 2, | 95 | KLMD_SHA_256 = CRYPT_S390_KLMD | 2, |
96 | KLMD_SHA_512 = CRYPT_S390_KLMD | 3, | ||
95 | }; | 97 | }; |
96 | 98 | ||
97 | /* | 99 | /* |
diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h index b7a52ab5db9..1ceafa571ea 100644 --- a/arch/s390/crypto/sha.h +++ b/arch/s390/crypto/sha.h | |||
@@ -19,11 +19,12 @@ | |||
19 | #include <crypto/sha.h> | 19 | #include <crypto/sha.h> |
20 | 20 | ||
21 | /* must be big enough for the largest SHA variant */ | 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 | struct s390_sha_ctx { | 25 | struct s390_sha_ctx { |
25 | u64 count; /* message length in bytes */ | 26 | u64 count; /* message length in bytes */ |
26 | u32 state[8]; | 27 | u32 state[SHA_MAX_STATE_SIZE]; |
27 | u8 buf[2 * SHA_MAX_BLOCK_SIZE]; | 28 | u8 buf[2 * SHA_MAX_BLOCK_SIZE]; |
28 | int func; /* KIMD function to use */ | 29 | int func; /* KIMD function to use */ |
29 | }; | 30 | }; |
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c new file mode 100644 index 00000000000..4d651bbce0f --- /dev/null +++ b/arch/s390/crypto/sha512_s390.c | |||
@@ -0,0 +1,71 @@ | |||
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"); | ||
diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c index 80b6f2ba005..9d6eb8c3d37 100644 --- a/arch/s390/crypto/sha_common.c +++ b/arch/s390/crypto/sha_common.c | |||
@@ -59,12 +59,15 @@ void s390_sha_final(struct crypto_tfm *tfm, u8 *out) | |||
59 | struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); | 59 | struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm); |
60 | unsigned int bsize = crypto_tfm_alg_blocksize(tfm); | 60 | unsigned int bsize = crypto_tfm_alg_blocksize(tfm); |
61 | u64 bits; | 61 | u64 bits; |
62 | unsigned int index, end; | 62 | unsigned int index, end, plen; |
63 | int ret; | 63 | int ret; |
64 | 64 | ||
65 | /* SHA-512 uses 128 bit padding length */ | ||
66 | plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8; | ||
67 | |||
65 | /* must perform manual padding */ | 68 | /* must perform manual padding */ |
66 | index = ctx->count & (bsize - 1); | 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 | /* start pad with 1 */ | 72 | /* start pad with 1 */ |
70 | ctx->buf[index] = 0x80; | 73 | ctx->buf[index] = 0x80; |
@@ -73,6 +76,10 @@ void s390_sha_final(struct crypto_tfm *tfm, u8 *out) | |||
73 | /* pad with zeros */ | 76 | /* pad with zeros */ |
74 | memset(ctx->buf + index, 0x00, end - index - 8); | 77 | memset(ctx->buf + index, 0x00, end - index - 8); |
75 | 78 | ||
79 | /* | ||
80 | * Append message length. Well, SHA-512 wants a 128 bit lenght value, | ||
81 | * nevertheless we use u64, should be enough for now... | ||
82 | */ | ||
76 | bits = ctx->count * 8; | 83 | bits = ctx->count * 8; |
77 | memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); | 84 | memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); |
78 | 85 | ||