Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Cryptographic API. | |
3 | * | |
c1e26e1e | 4 | * s390 implementation of the DES Cipher Algorithm. |
1da177e4 LT |
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> | |
1da177e4 | 18 | #include <linux/crypto.h> |
c1357833 | 19 | |
c1e26e1e | 20 | #include "crypt_s390.h" |
1da177e4 LT |
21 | #include "crypto_des.h" |
22 | ||
23 | #define DES_BLOCK_SIZE 8 | |
24 | #define DES_KEY_SIZE 8 | |
25 | ||
26 | #define DES3_128_KEY_SIZE (2 * DES_KEY_SIZE) | |
27 | #define DES3_128_BLOCK_SIZE DES_BLOCK_SIZE | |
28 | ||
29 | #define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE) | |
30 | #define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE | |
31 | ||
c1e26e1e | 32 | struct crypt_s390_des_ctx { |
1da177e4 LT |
33 | u8 iv[DES_BLOCK_SIZE]; |
34 | u8 key[DES_KEY_SIZE]; | |
35 | }; | |
36 | ||
c1e26e1e | 37 | struct crypt_s390_des3_128_ctx { |
1da177e4 LT |
38 | u8 iv[DES_BLOCK_SIZE]; |
39 | u8 key[DES3_128_KEY_SIZE]; | |
40 | }; | |
41 | ||
c1e26e1e | 42 | struct crypt_s390_des3_192_ctx { |
1da177e4 LT |
43 | u8 iv[DES_BLOCK_SIZE]; |
44 | u8 key[DES3_192_KEY_SIZE]; | |
45 | }; | |
46 | ||
c1357833 JG |
47 | static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, |
48 | u32 *flags) | |
1da177e4 | 49 | { |
c1357833 | 50 | struct crypt_s390_des_ctx *dctx = ctx; |
1da177e4 LT |
51 | int ret; |
52 | ||
c1357833 | 53 | /* test if key is valid (not a weak key) */ |
1da177e4 | 54 | ret = crypto_des_check_key(key, keylen, flags); |
c1357833 | 55 | if (ret == 0) |
1da177e4 | 56 | memcpy(dctx->key, key, keylen); |
1da177e4 LT |
57 | return ret; |
58 | } | |
59 | ||
c1357833 | 60 | static void des_encrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 61 | { |
c1357833 | 62 | struct crypt_s390_des_ctx *dctx = ctx; |
1da177e4 | 63 | |
c1e26e1e | 64 | crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); |
1da177e4 LT |
65 | } |
66 | ||
c1357833 | 67 | static void des_decrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 68 | { |
c1357833 | 69 | struct crypt_s390_des_ctx *dctx = ctx; |
1da177e4 | 70 | |
c1e26e1e | 71 | crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); |
1da177e4 LT |
72 | } |
73 | ||
74 | static struct crypto_alg des_alg = { | |
75 | .cra_name = "des", | |
76 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | |
77 | .cra_blocksize = DES_BLOCK_SIZE, | |
c1e26e1e | 78 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), |
1da177e4 LT |
79 | .cra_module = THIS_MODULE, |
80 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), | |
c1357833 JG |
81 | .cra_u = { |
82 | .cipher = { | |
83 | .cia_min_keysize = DES_KEY_SIZE, | |
84 | .cia_max_keysize = DES_KEY_SIZE, | |
85 | .cia_setkey = des_setkey, | |
86 | .cia_encrypt = des_encrypt, | |
87 | .cia_decrypt = des_decrypt | |
88 | } | |
89 | } | |
1da177e4 LT |
90 | }; |
91 | ||
92 | /* | |
93 | * RFC2451: | |
94 | * | |
95 | * For DES-EDE3, there is no known need to reject weak or | |
96 | * complementation keys. Any weakness is obviated by the use of | |
97 | * multiple keys. | |
98 | * | |
99 | * However, if the two independent 64-bit keys are equal, | |
100 | * then the DES3 operation is simply the same as DES. | |
101 | * Implementers MUST reject keys that exhibit this property. | |
102 | * | |
103 | */ | |
c1357833 JG |
104 | static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, |
105 | u32 *flags) | |
1da177e4 LT |
106 | { |
107 | int i, ret; | |
c1357833 | 108 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
1da177e4 LT |
109 | const u8* temp_key = key; |
110 | ||
1da177e4 | 111 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { |
1da177e4 LT |
112 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; |
113 | return -EINVAL; | |
114 | } | |
c1357833 | 115 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { |
1da177e4 LT |
116 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); |
117 | if (ret < 0) | |
118 | return ret; | |
119 | } | |
120 | memcpy(dctx->key, key, keylen); | |
121 | return 0; | |
122 | } | |
123 | ||
c1357833 | 124 | static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 125 | { |
c1357833 | 126 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
1da177e4 | 127 | |
c1e26e1e | 128 | crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, |
c1357833 | 129 | DES3_128_BLOCK_SIZE); |
1da177e4 LT |
130 | } |
131 | ||
c1357833 | 132 | static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 133 | { |
c1357833 | 134 | struct crypt_s390_des3_128_ctx *dctx = ctx; |
1da177e4 | 135 | |
c1e26e1e | 136 | crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, |
c1357833 | 137 | DES3_128_BLOCK_SIZE); |
1da177e4 LT |
138 | } |
139 | ||
140 | static struct crypto_alg des3_128_alg = { | |
141 | .cra_name = "des3_ede128", | |
142 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | |
143 | .cra_blocksize = DES3_128_BLOCK_SIZE, | |
c1e26e1e | 144 | .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), |
1da177e4 LT |
145 | .cra_module = THIS_MODULE, |
146 | .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), | |
c1357833 JG |
147 | .cra_u = { |
148 | .cipher = { | |
149 | .cia_min_keysize = DES3_128_KEY_SIZE, | |
150 | .cia_max_keysize = DES3_128_KEY_SIZE, | |
151 | .cia_setkey = des3_128_setkey, | |
152 | .cia_encrypt = des3_128_encrypt, | |
153 | .cia_decrypt = des3_128_decrypt | |
154 | } | |
155 | } | |
1da177e4 LT |
156 | }; |
157 | ||
158 | /* | |
159 | * RFC2451: | |
160 | * | |
161 | * For DES-EDE3, there is no known need to reject weak or | |
162 | * complementation keys. Any weakness is obviated by the use of | |
163 | * multiple keys. | |
164 | * | |
165 | * However, if the first two or last two independent 64-bit keys are | |
166 | * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the | |
167 | * same as DES. Implementers MUST reject keys that exhibit this | |
168 | * property. | |
169 | * | |
170 | */ | |
c1357833 JG |
171 | static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, |
172 | u32 *flags) | |
1da177e4 LT |
173 | { |
174 | int i, ret; | |
c1357833 JG |
175 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
176 | const u8* temp_key = key; | |
1da177e4 | 177 | |
1da177e4 LT |
178 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
179 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | |
c1357833 | 180 | DES_KEY_SIZE))) { |
1da177e4 LT |
181 | |
182 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | |
183 | return -EINVAL; | |
184 | } | |
185 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { | |
186 | ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags); | |
c1357833 | 187 | if (ret < 0) |
1da177e4 | 188 | return ret; |
1da177e4 LT |
189 | } |
190 | memcpy(dctx->key, key, keylen); | |
191 | return 0; | |
192 | } | |
193 | ||
c1357833 | 194 | static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 195 | { |
c1357833 | 196 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
1da177e4 | 197 | |
c1e26e1e | 198 | crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, |
c1357833 | 199 | DES3_192_BLOCK_SIZE); |
1da177e4 LT |
200 | } |
201 | ||
c1357833 | 202 | static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) |
1da177e4 | 203 | { |
c1357833 | 204 | struct crypt_s390_des3_192_ctx *dctx = ctx; |
1da177e4 | 205 | |
c1e26e1e | 206 | crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, |
c1357833 | 207 | DES3_192_BLOCK_SIZE); |
1da177e4 LT |
208 | } |
209 | ||
210 | static struct crypto_alg des3_192_alg = { | |
211 | .cra_name = "des3_ede", | |
212 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | |
213 | .cra_blocksize = DES3_192_BLOCK_SIZE, | |
c1e26e1e | 214 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), |
1da177e4 LT |
215 | .cra_module = THIS_MODULE, |
216 | .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), | |
c1357833 JG |
217 | .cra_u = { |
218 | .cipher = { | |
219 | .cia_min_keysize = DES3_192_KEY_SIZE, | |
220 | .cia_max_keysize = DES3_192_KEY_SIZE, | |
221 | .cia_setkey = des3_192_setkey, | |
222 | .cia_encrypt = des3_192_encrypt, | |
223 | .cia_decrypt = des3_192_decrypt | |
224 | } | |
225 | } | |
1da177e4 LT |
226 | }; |
227 | ||
c1357833 | 228 | static int init(void) |
1da177e4 | 229 | { |
c1357833 | 230 | int ret = 0; |
1da177e4 | 231 | |
c1e26e1e JG |
232 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || |
233 | !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) || | |
c1357833 | 234 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) |
1da177e4 | 235 | return -ENOSYS; |
1da177e4 | 236 | |
c1357833 JG |
237 | ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1; |
238 | ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2; | |
239 | ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4; | |
240 | if (ret) { | |
1da177e4 LT |
241 | crypto_unregister_alg(&des3_192_alg); |
242 | crypto_unregister_alg(&des3_128_alg); | |
243 | crypto_unregister_alg(&des_alg); | |
244 | return -EEXIST; | |
245 | } | |
1da177e4 LT |
246 | return 0; |
247 | } | |
248 | ||
c1357833 | 249 | static void __exit fini(void) |
1da177e4 LT |
250 | { |
251 | crypto_unregister_alg(&des3_192_alg); | |
252 | crypto_unregister_alg(&des3_128_alg); | |
253 | crypto_unregister_alg(&des_alg); | |
254 | } | |
255 | ||
256 | module_init(init); | |
257 | module_exit(fini); | |
258 | ||
259 | MODULE_ALIAS("des"); | |
260 | MODULE_ALIAS("des3_ede"); | |
261 | ||
262 | MODULE_LICENSE("GPL"); | |
263 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); |