aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/crypto')
-rw-r--r--arch/s390/crypto/Kconfig60
-rw-r--r--arch/s390/crypto/Makefile3
-rw-r--r--arch/s390/crypto/aes_s390.c47
-rw-r--r--arch/s390/crypto/crypt_s390.h281
-rw-r--r--arch/s390/crypto/crypt_s390_query.c129
-rw-r--r--arch/s390/crypto/des_check_key.c6
-rw-r--r--arch/s390/crypto/des_s390.c8
-rw-r--r--arch/s390/crypto/prng.c213
-rw-r--r--arch/s390/crypto/sha1_s390.c83
-rw-r--r--arch/s390/crypto/sha256_s390.c11
10 files changed, 484 insertions, 357 deletions
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
new file mode 100644
index 000000000000..99ff9f08e4d7
--- /dev/null
+++ b/arch/s390/crypto/Kconfig
@@ -0,0 +1,60 @@
1config CRYPTO_SHA1_S390
2 tristate "SHA1 digest algorithm"
3 depends on S390
4 select CRYPTO_ALGAPI
5 help
6 This is the s390 hardware accelerated implementation of the
7 SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
8
9config CRYPTO_SHA256_S390
10 tristate "SHA256 digest algorithm"
11 depends on S390
12 select CRYPTO_ALGAPI
13 help
14 This is the s390 hardware accelerated implementation of the
15 SHA256 secure hash standard (DFIPS 180-2).
16
17 This version of SHA implements a 256 bit hash with 128 bits of
18 security against collision attacks.
19
20config CRYPTO_DES_S390
21 tristate "DES and Triple DES cipher algorithms"
22 depends on S390
23 select CRYPTO_ALGAPI
24 select CRYPTO_BLKCIPHER
25 help
26 This us the s390 hardware accelerated implementation of the
27 DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
28
29config CRYPTO_AES_S390
30 tristate "AES cipher algorithms"
31 depends on S390
32 select CRYPTO_ALGAPI
33 select CRYPTO_BLKCIPHER
34 help
35 This is the s390 hardware accelerated implementation of the
36 AES cipher algorithms (FIPS-197). AES uses the Rijndael
37 algorithm.
38
39 Rijndael appears to be consistently a very good performer in
40 both hardware and software across a wide range of computing
41 environments regardless of its use in feedback or non-feedback
42 modes. Its key setup time is excellent, and its key agility is
43 good. Rijndael's very low memory requirements make it very well
44 suited for restricted-space environments, in which it also
45 demonstrates excellent performance. Rijndael's operations are
46 among the easiest to defend against power and timing attacks.
47
48 On s390 the System z9-109 currently only supports the key size
49 of 128 bit.
50
51config S390_PRNG
52 tristate "Pseudo random number generator device driver"
53 depends on S390
54 default "m"
55 help
56 Select this option if you want to use the s390 pseudo random number
57 generator. The PRNG is part of the cryptograhic processor functions
58 and uses triple-DES to generate secure random numbers like the
59 ANSI X9.17 standard. The PRNG is usable via the char device
60 /dev/prandom.
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index bfe2541dc5cf..14e552c5cc43 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -6,5 +6,4 @@ obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o
6obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o 6obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o
7obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o 7obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o
8obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o 8obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
9 9obj-$(CONFIG_S390_PRNG) += prng.o
10obj-$(CONFIG_CRYPTO_TEST) += crypt_s390_query.o
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 15c9eec02928..91636353f6f0 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -4,7 +4,7 @@
4 * s390 implementation of the AES Cipher Algorithm. 4 * s390 implementation of the AES Cipher Algorithm.
5 * 5 *
6 * s390 Version: 6 * s390 Version:
7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation 7 * Copyright IBM Corp. 2005,2007
8 * Author(s): Jan Glauber (jang@de.ibm.com) 8 * Author(s): Jan Glauber (jang@de.ibm.com)
9 * 9 *
10 * Derived from "crypto/aes.c" 10 * Derived from "crypto/aes.c"
@@ -27,9 +27,11 @@
27/* data block size for all key lengths */ 27/* data block size for all key lengths */
28#define AES_BLOCK_SIZE 16 28#define AES_BLOCK_SIZE 16
29 29
30int has_aes_128 = 0; 30#define AES_KEYLEN_128 1
31int has_aes_192 = 0; 31#define AES_KEYLEN_192 2
32int has_aes_256 = 0; 32#define AES_KEYLEN_256 4
33
34static char keylen_flag = 0;
33 35
34struct s390_aes_ctx { 36struct s390_aes_ctx {
35 u8 iv[AES_BLOCK_SIZE]; 37 u8 iv[AES_BLOCK_SIZE];
@@ -47,20 +49,19 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
47 49
48 switch (key_len) { 50 switch (key_len) {
49 case 16: 51 case 16:
50 if (!has_aes_128) 52 if (!(keylen_flag & AES_KEYLEN_128))
51 goto fail; 53 goto fail;
52 break; 54 break;
53 case 24: 55 case 24:
54 if (!has_aes_192) 56 if (!(keylen_flag & AES_KEYLEN_192))
55 goto fail; 57 goto fail;
56 58
57 break; 59 break;
58 case 32: 60 case 32:
59 if (!has_aes_256) 61 if (!(keylen_flag & AES_KEYLEN_256))
60 goto fail; 62 goto fail;
61 break; 63 break;
62 default: 64 default:
63 /* invalid key length */
64 goto fail; 65 goto fail;
65 break; 66 break;
66 } 67 }
@@ -322,34 +323,32 @@ static int __init aes_init(void)
322 int ret; 323 int ret;
323 324
324 if (crypt_s390_func_available(KM_AES_128_ENCRYPT)) 325 if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
325 has_aes_128 = 1; 326 keylen_flag |= AES_KEYLEN_128;
326 if (crypt_s390_func_available(KM_AES_192_ENCRYPT)) 327 if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
327 has_aes_192 = 1; 328 keylen_flag |= AES_KEYLEN_192;
328 if (crypt_s390_func_available(KM_AES_256_ENCRYPT)) 329 if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
329 has_aes_256 = 1; 330 keylen_flag |= AES_KEYLEN_256;
331
332 if (!keylen_flag)
333 return -EOPNOTSUPP;
330 334
331 if (!has_aes_128 && !has_aes_192 && !has_aes_256) 335 /* z9 109 and z9 BC/EC only support 128 bit key length */
332 return -ENOSYS; 336 if (keylen_flag == AES_KEYLEN_128)
337 printk(KERN_INFO
338 "aes_s390: hardware acceleration only available for"
339 "128 bit keys\n");
333 340
334 ret = crypto_register_alg(&aes_alg); 341 ret = crypto_register_alg(&aes_alg);
335 if (ret != 0) { 342 if (ret)
336 printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
337 goto aes_err; 343 goto aes_err;
338 }
339 344
340 ret = crypto_register_alg(&ecb_aes_alg); 345 ret = crypto_register_alg(&ecb_aes_alg);
341 if (ret != 0) { 346 if (ret)
342 printk(KERN_INFO
343 "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
344 goto ecb_aes_err; 347 goto ecb_aes_err;
345 }
346 348
347 ret = crypto_register_alg(&cbc_aes_alg); 349 ret = crypto_register_alg(&cbc_aes_alg);
348 if (ret != 0) { 350 if (ret)
349 printk(KERN_INFO
350 "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
351 goto cbc_aes_err; 351 goto cbc_aes_err;
352 }
353 352
354out: 353out:
355 return ret; 354 return ret;
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
index 2b137089f625..2775d2618332 100644
--- a/arch/s390/crypto/crypt_s390.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -3,8 +3,9 @@
3 * 3 *
4 * Support for s390 cryptographic instructions. 4 * Support for s390 cryptographic instructions.
5 * 5 *
6 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation 6 * Copyright IBM Corp. 2003,2007
7 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 7 * Author(s): Thomas Spatzier
8 * Jan Glauber (jan.glauber@de.ibm.com)
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify it 10 * 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 * under the terms of the GNU General Public License as published by the Free
@@ -32,7 +33,8 @@ enum crypt_s390_operations {
32 CRYPT_S390_KMAC = 0x0500 33 CRYPT_S390_KMAC = 0x0500
33}; 34};
34 35
35/* function codes for KM (CIPHER MESSAGE) instruction 36/*
37 * function codes for KM (CIPHER MESSAGE) instruction
36 * 0x80 is the decipher modifier bit 38 * 0x80 is the decipher modifier bit
37 */ 39 */
38enum crypt_s390_km_func { 40enum crypt_s390_km_func {
@@ -51,7 +53,8 @@ enum crypt_s390_km_func {
51 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, 53 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80,
52}; 54};
53 55
54/* function codes for KMC (CIPHER MESSAGE WITH CHAINING) 56/*
57 * function codes for KMC (CIPHER MESSAGE WITH CHAINING)
55 * instruction 58 * instruction
56 */ 59 */
57enum crypt_s390_kmc_func { 60enum crypt_s390_kmc_func {
@@ -68,9 +71,11 @@ enum crypt_s390_kmc_func {
68 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80, 71 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80,
69 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14, 72 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14,
70 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80, 73 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80,
74 KMC_PRNG = CRYPT_S390_KMC | 0x43,
71}; 75};
72 76
73/* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) 77/*
78 * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
74 * instruction 79 * instruction
75 */ 80 */
76enum crypt_s390_kimd_func { 81enum crypt_s390_kimd_func {
@@ -79,7 +84,8 @@ enum crypt_s390_kimd_func {
79 KIMD_SHA_256 = CRYPT_S390_KIMD | 2, 84 KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
80}; 85};
81 86
82/* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) 87/*
88 * function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
83 * instruction 89 * instruction
84 */ 90 */
85enum crypt_s390_klmd_func { 91enum crypt_s390_klmd_func {
@@ -88,7 +94,8 @@ enum crypt_s390_klmd_func {
88 KLMD_SHA_256 = CRYPT_S390_KLMD | 2, 94 KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
89}; 95};
90 96
91/* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) 97/*
98 * function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
92 * instruction 99 * instruction
93 */ 100 */
94enum crypt_s390_kmac_func { 101enum crypt_s390_kmac_func {
@@ -98,229 +105,219 @@ enum crypt_s390_kmac_func {
98 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3 105 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
99}; 106};
100 107
101/* status word for s390 crypto instructions' QUERY functions */ 108/**
102struct crypt_s390_query_status { 109 * crypt_s390_km:
103 u64 high; 110 * @func: the function code passed to KM; see crypt_s390_km_func
104 u64 low; 111 * @param: address of parameter block; see POP for details on each func
105}; 112 * @dest: address of destination memory area
106 113 * @src: address of source memory area
107/* 114 * @src_len: length of src operand in bytes
115 *
108 * Executes the KM (CIPHER MESSAGE) operation of the CPU. 116 * Executes the KM (CIPHER MESSAGE) operation of the CPU.
109 * @param func: the function code passed to KM; see crypt_s390_km_func 117 *
110 * @param param: address of parameter block; see POP for details on each func 118 * Returns -1 for failure, 0 for the query func, number of processed
111 * @param dest: address of destination memory area 119 * bytes for encryption/decryption funcs
112 * @param src: address of source memory area
113 * @param src_len: length of src operand in bytes
114 * @returns < zero for failure, 0 for the query func, number of processed bytes
115 * for encryption/decryption funcs
116 */ 120 */
117static inline int 121static inline int crypt_s390_km(long func, void *param,
118crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len) 122 u8 *dest, const u8 *src, long src_len)
119{ 123{
120 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 124 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
121 register void* __param asm("1") = param; 125 register void *__param asm("1") = param;
122 register const u8* __src asm("2") = src; 126 register const u8 *__src asm("2") = src;
123 register long __src_len asm("3") = src_len; 127 register long __src_len asm("3") = src_len;
124 register u8* __dest asm("4") = dest; 128 register u8 *__dest asm("4") = dest;
125 int ret; 129 int ret;
126 130
127 asm volatile( 131 asm volatile(
128 "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ 132 "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */
129 "1: brc 1,0b \n" /* handle partial completion */ 133 "1: brc 1,0b \n" /* handle partial completion */
130 " ahi %0,%h7\n" 134 " la %0,0\n"
131 "2: ahi %0,%h8\n" 135 "2:\n"
132 "3:\n" 136 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
133 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
134 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 137 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
135 : "d" (__func), "a" (__param), "0" (-EFAULT), 138 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
136 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
137 if (ret < 0) 139 if (ret < 0)
138 return ret; 140 return ret;
139 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 141 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
140} 142}
141 143
142/* 144/**
145 * crypt_s390_kmc:
146 * @func: the function code passed to KM; see crypt_s390_kmc_func
147 * @param: address of parameter block; see POP for details on each func
148 * @dest: address of destination memory area
149 * @src: address of source memory area
150 * @src_len: length of src operand in bytes
151 *
143 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU. 152 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
144 * @param func: the function code passed to KM; see crypt_s390_kmc_func 153 *
145 * @param param: address of parameter block; see POP for details on each func 154 * Returns -1 for failure, 0 for the query func, number of processed
146 * @param dest: address of destination memory area 155 * bytes for encryption/decryption funcs
147 * @param src: address of source memory area
148 * @param src_len: length of src operand in bytes
149 * @returns < zero for failure, 0 for the query func, number of processed bytes
150 * for encryption/decryption funcs
151 */ 156 */
152static inline int 157static inline int crypt_s390_kmc(long func, void *param,
153crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len) 158 u8 *dest, const u8 *src, long src_len)
154{ 159{
155 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 160 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
156 register void* __param asm("1") = param; 161 register void *__param asm("1") = param;
157 register const u8* __src asm("2") = src; 162 register const u8 *__src asm("2") = src;
158 register long __src_len asm("3") = src_len; 163 register long __src_len asm("3") = src_len;
159 register u8* __dest asm("4") = dest; 164 register u8 *__dest asm("4") = dest;
160 int ret; 165 int ret;
161 166
162 asm volatile( 167 asm volatile(
163 "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ 168 "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */
164 "1: brc 1,0b \n" /* handle partial completion */ 169 "1: brc 1,0b \n" /* handle partial completion */
165 " ahi %0,%h7\n" 170 " la %0,0\n"
166 "2: ahi %0,%h8\n" 171 "2:\n"
167 "3:\n" 172 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
168 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
169 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) 173 : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest)
170 : "d" (__func), "a" (__param), "0" (-EFAULT), 174 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
171 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
172 if (ret < 0) 175 if (ret < 0)
173 return ret; 176 return ret;
174 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 177 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
175} 178}
176 179
177/* 180/**
181 * crypt_s390_kimd:
182 * @func: the function code passed to KM; see crypt_s390_kimd_func
183 * @param: address of parameter block; see POP for details on each func
184 * @src: address of source memory area
185 * @src_len: length of src operand in bytes
186 *
178 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 187 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
179 * of the CPU. 188 * of the CPU.
180 * @param func: the function code passed to KM; see crypt_s390_kimd_func 189 *
181 * @param param: address of parameter block; see POP for details on each func 190 * Returns -1 for failure, 0 for the query func, number of processed
182 * @param src: address of source memory area 191 * bytes for digest funcs
183 * @param src_len: length of src operand in bytes
184 * @returns < zero for failure, 0 for the query func, number of processed bytes
185 * for digest funcs
186 */ 192 */
187static inline int 193static inline int crypt_s390_kimd(long func, void *param,
188crypt_s390_kimd(long func, void* param, const u8* src, long src_len) 194 const u8 *src, long src_len)
189{ 195{
190 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 196 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
191 register void* __param asm("1") = param; 197 register void *__param asm("1") = param;
192 register const u8* __src asm("2") = src; 198 register const u8 *__src asm("2") = src;
193 register long __src_len asm("3") = src_len; 199 register long __src_len asm("3") = src_len;
194 int ret; 200 int ret;
195 201
196 asm volatile( 202 asm volatile(
197 "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ 203 "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */
198 "1: brc 1,0b \n" /* handle partial completion */ 204 "1: brc 1,0b \n" /* handle partial completion */
199 " ahi %0,%h6\n" 205 " la %0,0\n"
200 "2: ahi %0,%h7\n" 206 "2:\n"
201 "3:\n" 207 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
202 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
203 : "=d" (ret), "+a" (__src), "+d" (__src_len) 208 : "=d" (ret), "+a" (__src), "+d" (__src_len)
204 : "d" (__func), "a" (__param), "0" (-EFAULT), 209 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
205 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
206 if (ret < 0) 210 if (ret < 0)
207 return ret; 211 return ret;
208 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 212 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
209} 213}
210 214
211/* 215/**
216 * crypt_s390_klmd:
217 * @func: the function code passed to KM; see crypt_s390_klmd_func
218 * @param: address of parameter block; see POP for details on each func
219 * @src: address of source memory area
220 * @src_len: length of src operand in bytes
221 *
212 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU. 222 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
213 * @param func: the function code passed to KM; see crypt_s390_klmd_func 223 *
214 * @param param: address of parameter block; see POP for details on each func 224 * Returns -1 for failure, 0 for the query func, number of processed
215 * @param src: address of source memory area 225 * bytes for digest funcs
216 * @param src_len: length of src operand in bytes
217 * @returns < zero for failure, 0 for the query func, number of processed bytes
218 * for digest funcs
219 */ 226 */
220static inline int 227static inline int crypt_s390_klmd(long func, void *param,
221crypt_s390_klmd(long func, void* param, const u8* src, long src_len) 228 const u8 *src, long src_len)
222{ 229{
223 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 230 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
224 register void* __param asm("1") = param; 231 register void *__param asm("1") = param;
225 register const u8* __src asm("2") = src; 232 register const u8 *__src asm("2") = src;
226 register long __src_len asm("3") = src_len; 233 register long __src_len asm("3") = src_len;
227 int ret; 234 int ret;
228 235
229 asm volatile( 236 asm volatile(
230 "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ 237 "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */
231 "1: brc 1,0b \n" /* handle partial completion */ 238 "1: brc 1,0b \n" /* handle partial completion */
232 " ahi %0,%h6\n" 239 " la %0,0\n"
233 "2: ahi %0,%h7\n" 240 "2:\n"
234 "3:\n" 241 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
235 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
236 : "=d" (ret), "+a" (__src), "+d" (__src_len) 242 : "=d" (ret), "+a" (__src), "+d" (__src_len)
237 : "d" (__func), "a" (__param), "0" (-EFAULT), 243 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
238 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
239 if (ret < 0) 244 if (ret < 0)
240 return ret; 245 return ret;
241 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 246 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
242} 247}
243 248
244/* 249/**
250 * crypt_s390_kmac:
251 * @func: the function code passed to KM; see crypt_s390_klmd_func
252 * @param: address of parameter block; see POP for details on each func
253 * @src: address of source memory area
254 * @src_len: length of src operand in bytes
255 *
245 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 256 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
246 * of the CPU. 257 * of the CPU.
247 * @param func: the function code passed to KM; see crypt_s390_klmd_func 258 *
248 * @param param: address of parameter block; see POP for details on each func 259 * Returns -1 for failure, 0 for the query func, number of processed
249 * @param src: address of source memory area 260 * bytes for digest funcs
250 * @param src_len: length of src operand in bytes
251 * @returns < zero for failure, 0 for the query func, number of processed bytes
252 * for digest funcs
253 */ 261 */
254static inline int 262static inline int crypt_s390_kmac(long func, void *param,
255crypt_s390_kmac(long func, void* param, const u8* src, long src_len) 263 const u8 *src, long src_len)
256{ 264{
257 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; 265 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
258 register void* __param asm("1") = param; 266 register void *__param asm("1") = param;
259 register const u8* __src asm("2") = src; 267 register const u8 *__src asm("2") = src;
260 register long __src_len asm("3") = src_len; 268 register long __src_len asm("3") = src_len;
261 int ret; 269 int ret;
262 270
263 asm volatile( 271 asm volatile(
264 "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ 272 "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */
265 "1: brc 1,0b \n" /* handle partial completion */ 273 "1: brc 1,0b \n" /* handle partial completion */
266 " ahi %0,%h6\n" 274 " la %0,0\n"
267 "2: ahi %0,%h7\n" 275 "2:\n"
268 "3:\n" 276 EX_TABLE(0b,2b) EX_TABLE(1b,2b)
269 EX_TABLE(0b,3b) EX_TABLE(1b,2b)
270 : "=d" (ret), "+a" (__src), "+d" (__src_len) 277 : "=d" (ret), "+a" (__src), "+d" (__src_len)
271 : "d" (__func), "a" (__param), "0" (-EFAULT), 278 : "d" (__func), "a" (__param), "0" (-1) : "cc", "memory");
272 "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory");
273 if (ret < 0) 279 if (ret < 0)
274 return ret; 280 return ret;
275 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; 281 return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
276} 282}
277 283
278/** 284/**
285 * crypt_s390_func_available:
286 * @func: the function code of the specific function; 0 if op in general
287 *
279 * Tests if a specific crypto function is implemented on the machine. 288 * Tests if a specific crypto function is implemented on the machine.
280 * @param func: the function code of the specific function; 0 if op in general 289 *
281 * @return 1 if func available; 0 if func or op in general not available 290 * Returns 1 if func available; 0 if func or op in general not available
282 */ 291 */
283static inline int 292static inline int crypt_s390_func_available(int func)
284crypt_s390_func_available(int func)
285{ 293{
294 unsigned char status[16];
286 int ret; 295 int ret;
287 296
288 struct crypt_s390_query_status status = { 297 switch (func & CRYPT_S390_OP_MASK) {
289 .high = 0, 298 case CRYPT_S390_KM:
290 .low = 0 299 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
291 }; 300 break;
292 switch (func & CRYPT_S390_OP_MASK){ 301 case CRYPT_S390_KMC:
293 case CRYPT_S390_KM: 302 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
294 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0); 303 break;
295 break; 304 case CRYPT_S390_KIMD:
296 case CRYPT_S390_KMC: 305 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
297 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0); 306 break;
298 break; 307 case CRYPT_S390_KLMD:
299 case CRYPT_S390_KIMD: 308 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
300 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0); 309 break;
301 break; 310 case CRYPT_S390_KMAC:
302 case CRYPT_S390_KLMD: 311 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
303 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0); 312 break;
304 break; 313 default:
305 case CRYPT_S390_KMAC: 314 return 0;
306 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
307 break;
308 default:
309 ret = 0;
310 return ret;
311 }
312 if (ret >= 0){
313 func &= CRYPT_S390_FUNC_MASK;
314 func &= 0x7f; //mask modifier bit
315 if (func < 64){
316 ret = (status.high >> (64 - func - 1)) & 0x1;
317 } else {
318 ret = (status.low >> (128 - func - 1)) & 0x1;
319 }
320 } else {
321 ret = 0;
322 } 315 }
323 return ret; 316 if (ret < 0)
317 return 0;
318 func &= CRYPT_S390_FUNC_MASK;
319 func &= 0x7f; /* mask modifier bit */
320 return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
324} 321}
325 322
326#endif // _CRYPTO_ARCH_S390_CRYPT_S390_H 323#endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */
diff --git a/arch/s390/crypto/crypt_s390_query.c b/arch/s390/crypto/crypt_s390_query.c
deleted file mode 100644
index 54fb11d7fadd..000000000000
--- a/arch/s390/crypto/crypt_s390_query.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for s390 cryptographic instructions.
5 * Testing module for querying processor crypto capabilities.
6 *
7 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
8 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <asm/errno.h>
20#include "crypt_s390.h"
21
22static void query_available_functions(void)
23{
24 printk(KERN_INFO "#####################\n");
25
26 /* query available KM functions */
27 printk(KERN_INFO "KM_QUERY: %d\n",
28 crypt_s390_func_available(KM_QUERY));
29 printk(KERN_INFO "KM_DEA: %d\n",
30 crypt_s390_func_available(KM_DEA_ENCRYPT));
31 printk(KERN_INFO "KM_TDEA_128: %d\n",
32 crypt_s390_func_available(KM_TDEA_128_ENCRYPT));
33 printk(KERN_INFO "KM_TDEA_192: %d\n",
34 crypt_s390_func_available(KM_TDEA_192_ENCRYPT));
35 printk(KERN_INFO "KM_AES_128: %d\n",
36 crypt_s390_func_available(KM_AES_128_ENCRYPT));
37 printk(KERN_INFO "KM_AES_192: %d\n",
38 crypt_s390_func_available(KM_AES_192_ENCRYPT));
39 printk(KERN_INFO "KM_AES_256: %d\n",
40 crypt_s390_func_available(KM_AES_256_ENCRYPT));
41
42 /* query available KMC functions */
43 printk(KERN_INFO "KMC_QUERY: %d\n",
44 crypt_s390_func_available(KMC_QUERY));
45 printk(KERN_INFO "KMC_DEA: %d\n",
46 crypt_s390_func_available(KMC_DEA_ENCRYPT));
47 printk(KERN_INFO "KMC_TDEA_128: %d\n",
48 crypt_s390_func_available(KMC_TDEA_128_ENCRYPT));
49 printk(KERN_INFO "KMC_TDEA_192: %d\n",
50 crypt_s390_func_available(KMC_TDEA_192_ENCRYPT));
51 printk(KERN_INFO "KMC_AES_128: %d\n",
52 crypt_s390_func_available(KMC_AES_128_ENCRYPT));
53 printk(KERN_INFO "KMC_AES_192: %d\n",
54 crypt_s390_func_available(KMC_AES_192_ENCRYPT));
55 printk(KERN_INFO "KMC_AES_256: %d\n",
56 crypt_s390_func_available(KMC_AES_256_ENCRYPT));
57
58 /* query available KIMD functions */
59 printk(KERN_INFO "KIMD_QUERY: %d\n",
60 crypt_s390_func_available(KIMD_QUERY));
61 printk(KERN_INFO "KIMD_SHA_1: %d\n",
62 crypt_s390_func_available(KIMD_SHA_1));
63 printk(KERN_INFO "KIMD_SHA_256: %d\n",
64 crypt_s390_func_available(KIMD_SHA_256));
65
66 /* query available KLMD functions */
67 printk(KERN_INFO "KLMD_QUERY: %d\n",
68 crypt_s390_func_available(KLMD_QUERY));
69 printk(KERN_INFO "KLMD_SHA_1: %d\n",
70 crypt_s390_func_available(KLMD_SHA_1));
71 printk(KERN_INFO "KLMD_SHA_256: %d\n",
72 crypt_s390_func_available(KLMD_SHA_256));
73
74 /* query available KMAC functions */
75 printk(KERN_INFO "KMAC_QUERY: %d\n",
76 crypt_s390_func_available(KMAC_QUERY));
77 printk(KERN_INFO "KMAC_DEA: %d\n",
78 crypt_s390_func_available(KMAC_DEA));
79 printk(KERN_INFO "KMAC_TDEA_128: %d\n",
80 crypt_s390_func_available(KMAC_TDEA_128));
81 printk(KERN_INFO "KMAC_TDEA_192: %d\n",
82 crypt_s390_func_available(KMAC_TDEA_192));
83}
84
85static int init(void)
86{
87 struct crypt_s390_query_status status = {
88 .high = 0,
89 .low = 0
90 };
91
92 printk(KERN_INFO "crypt_s390: querying available crypto functions\n");
93 crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
94 printk(KERN_INFO "KM:\t%016llx %016llx\n",
95 (unsigned long long) status.high,
96 (unsigned long long) status.low);
97 status.high = status.low = 0;
98 crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
99 printk(KERN_INFO "KMC:\t%016llx %016llx\n",
100 (unsigned long long) status.high,
101 (unsigned long long) status.low);
102 status.high = status.low = 0;
103 crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
104 printk(KERN_INFO "KIMD:\t%016llx %016llx\n",
105 (unsigned long long) status.high,
106 (unsigned long long) status.low);
107 status.high = status.low = 0;
108 crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
109 printk(KERN_INFO "KLMD:\t%016llx %016llx\n",
110 (unsigned long long) status.high,
111 (unsigned long long) status.low);
112 status.high = status.low = 0;
113 crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
114 printk(KERN_INFO "KMAC:\t%016llx %016llx\n",
115 (unsigned long long) status.high,
116 (unsigned long long) status.low);
117
118 query_available_functions();
119 return -ECANCELED;
120}
121
122static void __exit cleanup(void)
123{
124}
125
126module_init(init);
127module_exit(cleanup);
128
129MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/des_check_key.c b/arch/s390/crypto/des_check_key.c
index e3f5c5f238fe..5706af266442 100644
--- a/arch/s390/crypto/des_check_key.c
+++ b/arch/s390/crypto/des_check_key.c
@@ -10,8 +10,9 @@
10 * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL. 10 * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL.
11 * 11 *
12 * s390 Version: 12 * s390 Version:
13 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation 13 * Copyright IBM Corp. 2003
14 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 14 * Author(s): Thomas Spatzier
15 * Jan Glauber (jan.glauber@de.ibm.com)
15 * 16 *
16 * Derived from "crypto/des.c" 17 * Derived from "crypto/des.c"
17 * Copyright (c) 1992 Dana L. How. 18 * Copyright (c) 1992 Dana L. How.
@@ -30,6 +31,7 @@
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/errno.h> 32#include <linux/errno.h>
32#include <linux/crypto.h> 33#include <linux/crypto.h>
34#include "crypto_des.h"
33 35
34#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) 36#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o))
35 37
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index 2aba04852fe3..ea22707f435f 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -3,9 +3,9 @@
3 * 3 *
4 * s390 implementation of the DES Cipher Algorithm. 4 * s390 implementation of the DES Cipher Algorithm.
5 * 5 *
6 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright IBM Corp. 2003,2007
7 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 7 * Author(s): Thomas Spatzier
8 * 8 * Jan Glauber (jan.glauber@de.ibm.com)
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -557,7 +557,7 @@ static int init(void)
557 if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || 557 if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
558 !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) || 558 !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
559 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) 559 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
560 return -ENOSYS; 560 return -EOPNOTSUPP;
561 561
562 ret = crypto_register_alg(&des_alg); 562 ret = crypto_register_alg(&des_alg);
563 if (ret) 563 if (ret)
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
new file mode 100644
index 000000000000..8eb3a1aedc22
--- /dev/null
+++ b/arch/s390/crypto/prng.c
@@ -0,0 +1,213 @@
1/*
2 * Copyright IBM Corp. 2006,2007
3 * Author(s): Jan Glauber <jan.glauber@de.ibm.com>
4 * Driver for the s390 pseudo random number generator
5 */
6#include <linux/fs.h>
7#include <linux/init.h>
8#include <linux/kernel.h>
9#include <linux/miscdevice.h>
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/random.h>
13#include <asm/debug.h>
14#include <asm/uaccess.h>
15
16#include "crypt_s390.h"
17
18MODULE_LICENSE("GPL");
19MODULE_AUTHOR("Jan Glauber <jan.glauber@de.ibm.com>");
20MODULE_DESCRIPTION("s390 PRNG interface");
21
22static int prng_chunk_size = 256;
23module_param(prng_chunk_size, int, S_IRUSR | S_IRGRP | S_IROTH);
24MODULE_PARM_DESC(prng_chunk_size, "PRNG read chunk size in bytes");
25
26static int prng_entropy_limit = 4096;
27module_param(prng_entropy_limit, int, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
28MODULE_PARM_DESC(prng_entropy_limit,
29 "PRNG add entropy after that much bytes were produced");
30
31/*
32 * Any one who considers arithmetical methods of producing random digits is,
33 * of course, in a state of sin. -- John von Neumann
34 */
35
36struct s390_prng_data {
37 unsigned long count; /* how many bytes were produced */
38 char *buf;
39};
40
41static struct s390_prng_data *p;
42
43/* copied from libica, use a non-zero initial parameter block */
44static unsigned char parm_block[32] = {
450x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
460x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
47};
48
49static int prng_open(struct inode *inode, struct file *file)
50{
51 return nonseekable_open(inode, file);
52}
53
54static void prng_add_entropy(void)
55{
56 __u64 entropy[4];
57 unsigned int i;
58 int ret;
59
60 for (i = 0; i < 16; i++) {
61 ret = crypt_s390_kmc(KMC_PRNG, parm_block, (char *)entropy,
62 (char *)entropy, sizeof(entropy));
63 BUG_ON(ret < 0 || ret != sizeof(entropy));
64 memcpy(parm_block, entropy, sizeof(entropy));
65 }
66}
67
68static void prng_seed(int nbytes)
69{
70 char buf[16];
71 int i = 0;
72
73 BUG_ON(nbytes > 16);
74 get_random_bytes(buf, nbytes);
75
76 /* Add the entropy */
77 while (nbytes >= 8) {
78 *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8);
79 prng_add_entropy();
80 i += 8;
81 nbytes -= 8;
82 }
83 prng_add_entropy();
84}
85
86static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
87 loff_t *ppos)
88{
89 int chunk, n;
90 int ret = 0;
91 int tmp;
92
93 /* nbytes can be arbitrary long, we spilt it into chunks */
94 while (nbytes) {
95 /* same as in extract_entropy_user in random.c */
96 if (need_resched()) {
97 if (signal_pending(current)) {
98 if (ret == 0)
99 ret = -ERESTARTSYS;
100 break;
101 }
102 schedule();
103 }
104
105 /*
106 * we lose some random bytes if an attacker issues
107 * reads < 8 bytes, but we don't care
108 */
109 chunk = min_t(int, nbytes, prng_chunk_size);
110
111 /* PRNG only likes multiples of 8 bytes */
112 n = (chunk + 7) & -8;
113
114 if (p->count > prng_entropy_limit)
115 prng_seed(8);
116
117 /* if the CPU supports PRNG stckf is present too */
118 asm volatile(".insn s,0xb27c0000,%0"
119 : "=m" (*((unsigned long long *)p->buf)) : : "cc");
120
121 /*
122 * Beside the STCKF the input for the TDES-EDE is the output
123 * of the last operation. We differ here from X9.17 since we
124 * only store one timestamp into the buffer. Padding the whole
125 * buffer with timestamps does not improve security, since
126 * successive stckf have nearly constant offsets.
127 * If an attacker knows the first timestamp it would be
128 * trivial to guess the additional values. One timestamp
129 * is therefore enough and still guarantees unique input values.
130 *
131 * Note: you can still get strict X9.17 conformity by setting
132 * prng_chunk_size to 8 bytes.
133 */
134 tmp = crypt_s390_kmc(KMC_PRNG, parm_block, p->buf, p->buf, n);
135 BUG_ON((tmp < 0) || (tmp != n));
136
137 p->count += n;
138
139 if (copy_to_user(ubuf, p->buf, chunk))
140 return -EFAULT;
141
142 nbytes -= chunk;
143 ret += chunk;
144 ubuf += chunk;
145 }
146 return ret;
147}
148
149static struct file_operations prng_fops = {
150 .owner = THIS_MODULE,
151 .open = &prng_open,
152 .release = NULL,
153 .read = &prng_read,
154};
155
156static struct miscdevice prng_dev = {
157 .name = "prandom",
158 .minor = MISC_DYNAMIC_MINOR,
159 .fops = &prng_fops,
160};
161
162static int __init prng_init(void)
163{
164 int ret;
165
166 /* check if the CPU has a PRNG */
167 if (!crypt_s390_func_available(KMC_PRNG))
168 return -EOPNOTSUPP;
169
170 if (prng_chunk_size < 8)
171 return -EINVAL;
172
173 p = kmalloc(sizeof(struct s390_prng_data), GFP_KERNEL);
174 if (!p)
175 return -ENOMEM;
176 p->count = 0;
177
178 p->buf = kmalloc(prng_chunk_size, GFP_KERNEL);
179 if (!p->buf) {
180 ret = -ENOMEM;
181 goto out_free;
182 }
183
184 /* initialize the PRNG, add 128 bits of entropy */
185 prng_seed(16);
186
187 ret = misc_register(&prng_dev);
188 if (ret) {
189 printk(KERN_WARNING
190 "Could not register misc device for PRNG.\n");
191 goto out_buf;
192 }
193 return 0;
194
195out_buf:
196 kfree(p->buf);
197out_free:
198 kfree(p);
199 return ret;
200}
201
202static void __exit prng_exit(void)
203{
204 /* wipe me */
205 memset(p->buf, 0, prng_chunk_size);
206 kfree(p->buf);
207 kfree(p);
208
209 misc_deregister(&prng_dev);
210}
211
212module_init(prng_init);
213module_exit(prng_exit);
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index 49ca8690ee39..969639f31977 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -8,8 +8,9 @@
8 * implementation written by Steve Reid. 8 * implementation written by Steve Reid.
9 * 9 *
10 * s390 Version: 10 * s390 Version:
11 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation 11 * Copyright IBM Corp. 2003,2007
12 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 12 * Author(s): Thomas Spatzier
13 * Jan Glauber (jan.glauber@de.ibm.com)
13 * 14 *
14 * Derived from "crypto/sha1.c" 15 * Derived from "crypto/sha1.c"
15 * Copyright (c) Alan Smithee. 16 * Copyright (c) Alan Smithee.
@@ -43,16 +44,14 @@ struct crypt_s390_sha1_ctx {
43static void sha1_init(struct crypto_tfm *tfm) 44static void sha1_init(struct crypto_tfm *tfm)
44{ 45{
45 struct crypt_s390_sha1_ctx *ctx = crypto_tfm_ctx(tfm); 46 struct crypt_s390_sha1_ctx *ctx = crypto_tfm_ctx(tfm);
46 static const u32 initstate[5] = { 47
47 0x67452301, 48 ctx->state[0] = 0x67452301;
48 0xEFCDAB89, 49 ctx->state[1] = 0xEFCDAB89;
49 0x98BADCFE, 50 ctx->state[2] = 0x98BADCFE;
50 0x10325476, 51 ctx->state[3] = 0x10325476;
51 0xC3D2E1F0 52 ctx->state[4] = 0xC3D2E1F0;
52 };
53 53
54 ctx->count = 0; 54 ctx->count = 0;
55 memcpy(ctx->state, &initstate, sizeof(initstate));
56 ctx->buf_len = 0; 55 ctx->buf_len = 0;
57} 56}
58 57
@@ -63,13 +62,13 @@ static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
63 long imd_len; 62 long imd_len;
64 63
65 sctx = crypto_tfm_ctx(tfm); 64 sctx = crypto_tfm_ctx(tfm);
66 sctx->count += len * 8; //message bit length 65 sctx->count += len * 8; /* message bit length */
67 66
68 //anything in buffer yet? -> must be completed 67 /* anything in buffer yet? -> must be completed */
69 if (sctx->buf_len && (sctx->buf_len + len) >= SHA1_BLOCK_SIZE) { 68 if (sctx->buf_len && (sctx->buf_len + len) >= SHA1_BLOCK_SIZE) {
70 //complete full block and hash 69 /* complete full block and hash */
71 memcpy(sctx->buffer + sctx->buf_len, data, 70 memcpy(sctx->buffer + sctx->buf_len, data,
72 SHA1_BLOCK_SIZE - sctx->buf_len); 71 SHA1_BLOCK_SIZE - sctx->buf_len);
73 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, 72 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer,
74 SHA1_BLOCK_SIZE); 73 SHA1_BLOCK_SIZE);
75 data += SHA1_BLOCK_SIZE - sctx->buf_len; 74 data += SHA1_BLOCK_SIZE - sctx->buf_len;
@@ -77,37 +76,36 @@ static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
77 sctx->buf_len = 0; 76 sctx->buf_len = 0;
78 } 77 }
79 78
80 //rest of data contains full blocks? 79 /* rest of data contains full blocks? */
81 imd_len = len & ~0x3ful; 80 imd_len = len & ~0x3ful;
82 if (imd_len){ 81 if (imd_len) {
83 crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, imd_len); 82 crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, imd_len);
84 data += imd_len; 83 data += imd_len;
85 len -= imd_len; 84 len -= imd_len;
86 } 85 }
87 //anything left? store in buffer 86 /* anything left? store in buffer */
88 if (len){ 87 if (len) {
89 memcpy(sctx->buffer + sctx->buf_len , data, len); 88 memcpy(sctx->buffer + sctx->buf_len , data, len);
90 sctx->buf_len += len; 89 sctx->buf_len += len;
91 } 90 }
92} 91}
93 92
94 93
95static void 94static void pad_message(struct crypt_s390_sha1_ctx* sctx)
96pad_message(struct crypt_s390_sha1_ctx* sctx)
97{ 95{
98 int index; 96 int index;
99 97
100 index = sctx->buf_len; 98 index = sctx->buf_len;
101 sctx->buf_len = (sctx->buf_len < 56)? 99 sctx->buf_len = (sctx->buf_len < 56) ?
102 SHA1_BLOCK_SIZE:2 * SHA1_BLOCK_SIZE; 100 SHA1_BLOCK_SIZE:2 * SHA1_BLOCK_SIZE;
103 //start pad with 1 101 /* start pad with 1 */
104 sctx->buffer[index] = 0x80; 102 sctx->buffer[index] = 0x80;
105 //pad with zeros 103 /* pad with zeros */
106 index++; 104 index++;
107 memset(sctx->buffer + index, 0x00, sctx->buf_len - index); 105 memset(sctx->buffer + index, 0x00, sctx->buf_len - index);
108 //append length 106 /* append length */
109 memcpy(sctx->buffer + sctx->buf_len - 8, &sctx->count, 107 memcpy(sctx->buffer + sctx->buf_len - 8, &sctx->count,
110 sizeof sctx->count); 108 sizeof sctx->count);
111} 109}
112 110
113/* Add padding and return the message digest. */ 111/* Add padding and return the message digest. */
@@ -115,47 +113,40 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
115{ 113{
116 struct crypt_s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm); 114 struct crypt_s390_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
117 115
118 //must perform manual padding 116 /* must perform manual padding */
119 pad_message(sctx); 117 pad_message(sctx);
120 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len); 118 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len);
121 //copy digest to out 119 /* copy digest to out */
122 memcpy(out, sctx->state, SHA1_DIGEST_SIZE); 120 memcpy(out, sctx->state, SHA1_DIGEST_SIZE);
123 /* Wipe context */ 121 /* wipe context */
124 memset(sctx, 0, sizeof *sctx); 122 memset(sctx, 0, sizeof *sctx);
125} 123}
126 124
127static struct crypto_alg alg = { 125static struct crypto_alg alg = {
128 .cra_name = "sha1", 126 .cra_name = "sha1",
129 .cra_driver_name = "sha1-s390", 127 .cra_driver_name= "sha1-s390",
130 .cra_priority = CRYPT_S390_PRIORITY, 128 .cra_priority = CRYPT_S390_PRIORITY,
131 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 129 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
132 .cra_blocksize = SHA1_BLOCK_SIZE, 130 .cra_blocksize = SHA1_BLOCK_SIZE,
133 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx), 131 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx),
134 .cra_module = THIS_MODULE, 132 .cra_module = THIS_MODULE,
135 .cra_list = LIST_HEAD_INIT(alg.cra_list), 133 .cra_list = LIST_HEAD_INIT(alg.cra_list),
136 .cra_u = { .digest = { 134 .cra_u = { .digest = {
137 .dia_digestsize = SHA1_DIGEST_SIZE, 135 .dia_digestsize = SHA1_DIGEST_SIZE,
138 .dia_init = sha1_init, 136 .dia_init = sha1_init,
139 .dia_update = sha1_update, 137 .dia_update = sha1_update,
140 .dia_final = sha1_final } } 138 .dia_final = sha1_final } }
141}; 139};
142 140
143static int 141static int __init init(void)
144init(void)
145{ 142{
146 int ret = -ENOSYS; 143 if (!crypt_s390_func_available(KIMD_SHA_1))
144 return -EOPNOTSUPP;
147 145
148 if (crypt_s390_func_available(KIMD_SHA_1)){ 146 return crypto_register_alg(&alg);
149 ret = crypto_register_alg(&alg);
150 if (ret == 0){
151 printk(KERN_INFO "crypt_s390: sha1_s390 loaded.\n");
152 }
153 }
154 return ret;
155} 147}
156 148
157static void __exit 149static void __exit fini(void)
158fini(void)
159{ 150{
160 crypto_unregister_alg(&alg); 151 crypto_unregister_alg(&alg);
161} 152}
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index 8e4e67503fe7..78436c696d37 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -4,7 +4,7 @@
4 * s390 implementation of the SHA256 Secure Hash Algorithm. 4 * s390 implementation of the SHA256 Secure Hash Algorithm.
5 * 5 *
6 * s390 Version: 6 * s390 Version:
7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation 7 * Copyright IBM Corp. 2005,2007
8 * Author(s): Jan Glauber (jang@de.ibm.com) 8 * Author(s): Jan Glauber (jang@de.ibm.com)
9 * 9 *
10 * Derived from "crypto/sha256.c" 10 * Derived from "crypto/sha256.c"
@@ -143,15 +143,10 @@ static struct crypto_alg alg = {
143 143
144static int init(void) 144static int init(void)
145{ 145{
146 int ret;
147
148 if (!crypt_s390_func_available(KIMD_SHA_256)) 146 if (!crypt_s390_func_available(KIMD_SHA_256))
149 return -ENOSYS; 147 return -EOPNOTSUPP;
150 148
151 ret = crypto_register_alg(&alg); 149 return crypto_register_alg(&alg);
152 if (ret != 0)
153 printk(KERN_INFO "crypt_s390: sha256_s390 couldn't be loaded.");
154 return ret;
155} 150}
156 151
157static void __exit fini(void) 152static void __exit fini(void)