diff options
author | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-01-07 03:50:18 -0500 |
commit | ed03f430cdc8c802652467e9097606fedc2c7abc (patch) | |
tree | 30941ec1e6f93e99358fefe18175e5dd800a4379 /arch/s390/crypto/des_s390.c | |
parent | ed349a8a0a780ed27e2a765f16cee54d9b63bfee (diff) | |
parent | 6f957eaf79356a32e838f5f262ee9a60544b1d5b (diff) |
Pull pnpacpi into acpica branch
Diffstat (limited to 'arch/s390/crypto/des_s390.c')
-rw-r--r-- | arch/s390/crypto/des_s390.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c new file mode 100644 index 000000000000..a38bb2a3eef6 --- /dev/null +++ b/arch/s390/crypto/des_s390.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * s390 implementation of the DES Cipher Algorithm. | ||
5 | * | ||
6 | * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
7 | * Author(s): Thomas Spatzier (tspat@de.ibm.com) | ||
8 | * | ||
9 | * | ||
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 | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <asm/scatterlist.h> | ||
21 | #include <linux/crypto.h> | ||
22 | #include "crypt_s390.h" | ||
23 | #include "crypto_des.h" | ||
24 | |||
25 | #define DES_BLOCK_SIZE 8 | ||
26 | #define DES_KEY_SIZE 8 | ||
27 | |||
28 | #define DES3_128_KEY_SIZE (2 * DES_KEY_SIZE) | ||
29 | #define DES3_128_BLOCK_SIZE DES_BLOCK_SIZE | ||
30 | |||
31 | #define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE) | ||
32 | #define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE | ||
33 | |||
34 | struct crypt_s390_des_ctx { | ||
35 | u8 iv[DES_BLOCK_SIZE]; | ||
36 | u8 key[DES_KEY_SIZE]; | ||
37 | }; | ||
38 | |||
39 | struct crypt_s390_des3_128_ctx { | ||
40 | u8 iv[DES_BLOCK_SIZE]; | ||
41 | u8 key[DES3_128_KEY_SIZE]; | ||
42 | }; | ||
43 | |||
44 | struct crypt_s390_des3_192_ctx { | ||
45 | u8 iv[DES_BLOCK_SIZE]; | ||
46 | u8 key[DES3_192_KEY_SIZE]; | ||
47 | }; | ||
48 | |||
49 | static int | ||
50 | des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | ||
51 | { | ||
52 | struct crypt_s390_des_ctx *dctx; | ||
53 | int ret; | ||
54 | |||
55 | dctx = ctx; | ||
56 | //test if key is valid (not a weak key) | ||
57 | ret = crypto_des_check_key(key, keylen, flags); | ||
58 | if (ret == 0){ | ||
59 | memcpy(dctx->key, key, keylen); | ||
60 | } | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | |||
65 | static void | ||
66 | des_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
67 | { | ||
68 | struct crypt_s390_des_ctx *dctx; | ||
69 | |||
70 | dctx = ctx; | ||
71 | crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); | ||
72 | } | ||
73 | |||
74 | static void | ||
75 | des_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
76 | { | ||
77 | struct crypt_s390_des_ctx *dctx; | ||
78 | |||
79 | dctx = ctx; | ||
80 | crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); | ||
81 | } | ||
82 | |||
83 | static struct crypto_alg des_alg = { | ||
84 | .cra_name = "des", | ||
85 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
86 | .cra_blocksize = DES_BLOCK_SIZE, | ||
87 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), | ||
88 | .cra_module = THIS_MODULE, | ||
89 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), | ||
90 | .cra_u = { .cipher = { | ||
91 | .cia_min_keysize = DES_KEY_SIZE, | ||
92 | .cia_max_keysize = DES_KEY_SIZE, | ||
93 | .cia_setkey = des_setkey, | ||
94 | .cia_encrypt = des_encrypt, | ||
95 | .cia_decrypt = des_decrypt } } | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * RFC2451: | ||
100 | * | ||
101 | * For DES-EDE3, there is no known need to reject weak or | ||
102 | * complementation keys. Any weakness is obviated by the use of | ||
103 | * multiple keys. | ||
104 | * | ||
105 | * However, if the two independent 64-bit keys are equal, | ||
106 | * then the DES3 operation is simply the same as DES. | ||
107 | * Implementers MUST reject keys that exhibit this property. | ||
108 | * | ||
109 | */ | ||
110 | static int | ||
111 | des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | ||
112 | { | ||
113 | int i, ret; | ||
114 | struct crypt_s390_des3_128_ctx *dctx; | ||
115 | const u8* temp_key = key; | ||
116 | |||
117 | dctx = ctx; | ||
118 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { | ||
119 | |||
120 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { | ||
124 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); | ||
125 | if (ret < 0) | ||
126 | return ret; | ||
127 | } | ||
128 | memcpy(dctx->key, key, keylen); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void | ||
133 | des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
134 | { | ||
135 | struct crypt_s390_des3_128_ctx *dctx; | ||
136 | |||
137 | dctx = ctx; | ||
138 | crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, | ||
139 | DES3_128_BLOCK_SIZE); | ||
140 | } | ||
141 | |||
142 | static void | ||
143 | des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
144 | { | ||
145 | struct crypt_s390_des3_128_ctx *dctx; | ||
146 | |||
147 | dctx = ctx; | ||
148 | crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, | ||
149 | DES3_128_BLOCK_SIZE); | ||
150 | } | ||
151 | |||
152 | static struct crypto_alg des3_128_alg = { | ||
153 | .cra_name = "des3_ede128", | ||
154 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
155 | .cra_blocksize = DES3_128_BLOCK_SIZE, | ||
156 | .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), | ||
157 | .cra_module = THIS_MODULE, | ||
158 | .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), | ||
159 | .cra_u = { .cipher = { | ||
160 | .cia_min_keysize = DES3_128_KEY_SIZE, | ||
161 | .cia_max_keysize = DES3_128_KEY_SIZE, | ||
162 | .cia_setkey = des3_128_setkey, | ||
163 | .cia_encrypt = des3_128_encrypt, | ||
164 | .cia_decrypt = des3_128_decrypt } } | ||
165 | }; | ||
166 | |||
167 | /* | ||
168 | * RFC2451: | ||
169 | * | ||
170 | * For DES-EDE3, there is no known need to reject weak or | ||
171 | * complementation keys. Any weakness is obviated by the use of | ||
172 | * multiple keys. | ||
173 | * | ||
174 | * However, if the first two or last two independent 64-bit keys are | ||
175 | * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the | ||
176 | * same as DES. Implementers MUST reject keys that exhibit this | ||
177 | * property. | ||
178 | * | ||
179 | */ | ||
180 | static int | ||
181 | des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | ||
182 | { | ||
183 | int i, ret; | ||
184 | struct crypt_s390_des3_192_ctx *dctx; | ||
185 | const u8* temp_key; | ||
186 | |||
187 | dctx = ctx; | ||
188 | temp_key = key; | ||
189 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | ||
190 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | ||
191 | DES_KEY_SIZE))) { | ||
192 | |||
193 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { | ||
197 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); | ||
198 | if (ret < 0){ | ||
199 | return ret; | ||
200 | } | ||
201 | } | ||
202 | memcpy(dctx->key, key, keylen); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static void | ||
207 | des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
208 | { | ||
209 | struct crypt_s390_des3_192_ctx *dctx; | ||
210 | |||
211 | dctx = ctx; | ||
212 | crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, | ||
213 | DES3_192_BLOCK_SIZE); | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
218 | { | ||
219 | struct crypt_s390_des3_192_ctx *dctx; | ||
220 | |||
221 | dctx = ctx; | ||
222 | crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, | ||
223 | DES3_192_BLOCK_SIZE); | ||
224 | } | ||
225 | |||
226 | static struct crypto_alg des3_192_alg = { | ||
227 | .cra_name = "des3_ede", | ||
228 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
229 | .cra_blocksize = DES3_192_BLOCK_SIZE, | ||
230 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), | ||
231 | .cra_module = THIS_MODULE, | ||
232 | .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), | ||
233 | .cra_u = { .cipher = { | ||
234 | .cia_min_keysize = DES3_192_KEY_SIZE, | ||
235 | .cia_max_keysize = DES3_192_KEY_SIZE, | ||
236 | .cia_setkey = des3_192_setkey, | ||
237 | .cia_encrypt = des3_192_encrypt, | ||
238 | .cia_decrypt = des3_192_decrypt } } | ||
239 | }; | ||
240 | |||
241 | |||
242 | |||
243 | static int | ||
244 | init(void) | ||
245 | { | ||
246 | int ret; | ||
247 | |||
248 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || | ||
249 | !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) || | ||
250 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){ | ||
251 | return -ENOSYS; | ||
252 | } | ||
253 | |||
254 | ret = 0; | ||
255 | ret |= (crypto_register_alg(&des_alg) == 0)? 0:1; | ||
256 | ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2; | ||
257 | ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4; | ||
258 | if (ret){ | ||
259 | crypto_unregister_alg(&des3_192_alg); | ||
260 | crypto_unregister_alg(&des3_128_alg); | ||
261 | crypto_unregister_alg(&des_alg); | ||
262 | return -EEXIST; | ||
263 | } | ||
264 | |||
265 | printk(KERN_INFO "crypt_s390: des_s390 loaded.\n"); | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static void __exit | ||
270 | fini(void) | ||
271 | { | ||
272 | crypto_unregister_alg(&des3_192_alg); | ||
273 | crypto_unregister_alg(&des3_128_alg); | ||
274 | crypto_unregister_alg(&des_alg); | ||
275 | } | ||
276 | |||
277 | module_init(init); | ||
278 | module_exit(fini); | ||
279 | |||
280 | MODULE_ALIAS("des"); | ||
281 | MODULE_ALIAS("des3_ede"); | ||
282 | |||
283 | MODULE_LICENSE("GPL"); | ||
284 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); | ||