OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / openswan / linux / net / ipsec / aes / ipsec_alg_aes.c
1 /*
2  * ipsec_alg AES cipher stubs
3  *
4  * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
5  * 
6  * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
7  * 
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
12  * 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  * for more details.
17  *
18  * Fixes by:
19  *      PK:     Pawel Krawczyk <kravietz@aba.krakow.pl>
20  * Fixes list:
21  *      PK:     make XCBC comply with latest draft (keylength)
22  *
23  */
24 #include <linux/version.h>
25 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
26 #include <linux/config.h>
27 #endif
28 #include <linux/version.h>
29
30 /*      
31  *      special case: ipsec core modular with this static algo inside:
32  *      must avoid MODULE magic for this file
33  */
34 #if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
35 #undef MODULE
36 #endif
37
38 #include <linux/module.h>
39 #include <linux/init.h>
40
41 #include <linux/kernel.h> /* printk() */
42 #include <linux/errno.h>  /* error codes */
43 #include <linux/types.h>  /* size_t */
44 #include <linux/string.h>
45
46 /* Check if __exit is defined, if not null it */
47 #ifndef __exit
48 #define __exit
49 #endif
50
51 /*      Low freeswan header coupling    */
52 #include <openswan.h>
53 #include "openswan/ipsec_alg.h"
54 #include "klips-crypto/aes_cbc.h"
55
56 #define CONFIG_KLIPS_ENC_AES_MAC 1
57
58 #define AES_CONTEXT_T aes_context
59 static int debug_aes=0;
60 static int test_aes=0;
61 static int excl_aes=0;
62 static int keyminbits=0;
63 static int keymaxbits=0;
64 #if defined(CONFIG_KLIPS_ENC_AES_MODULE)
65 MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
66 #ifdef module_param
67 module_param(debug_aes,int,0664);
68 module_param(test_aes,int,0664);
69 module_param(excl_aes,int,0664);
70 module_param(keyminbits,int,0664);
71 module_param(keymaxbits,int,0664);
72 #else
73 MODULE_PARM(debug_aes, "i");
74 MODULE_PARM(test_aes, "i");
75 MODULE_PARM(excl_aes, "i");
76 MODULE_PARM(keyminbits, "i");
77 MODULE_PARM(keymaxbits, "i");
78 #endif
79 #endif
80
81 #if CONFIG_KLIPS_ENC_AES_MAC
82 #include "klips-crypto/aes_xcbc_mac.h"
83
84 /*      
85  *      Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
86  *      We use 9 for non-modular algorithm and none for modular, thus
87  *      forcing user to specify one on module load. -kravietz
88  */
89 #ifdef MODULE
90 static int auth_id=0;
91 #else
92 static int auth_id=9;
93 #endif
94 #if 0
95 #ifdef MODULE_PARM
96 MODULE_PARM(auth_id, "i");
97 #else
98 module_param(auth_id,int,0664);
99 #endif
100 #endif
101 #endif
102
103 #define ESP_AES                 12      /* truely _constant_  :)  */
104
105 /* 128, 192 or 256 */
106 #define ESP_AES_KEY_SZ_MIN      16      /* 128 bit secret key */
107 #define ESP_AES_KEY_SZ_MAX      32      /* 256 bit secret key */
108 #define ESP_AES_CBC_BLK_LEN     16      /* AES-CBC block size */
109
110 /* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
111  * -kravietz
112  */
113 #define ESP_AES_MAC_KEY_SZ      16      /* 128 bit MAC key */
114 #define ESP_AES_MAC_BLK_LEN     16      /* 128 bit block */
115
116 static int _aes_set_key(struct ipsec_alg_enc *alg,
117                         __u8 * key_e, const __u8 * key,
118                         size_t keysize)
119 {
120         int ret;
121         AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
122         ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
123         if (debug_aes > 0)
124                 printk(KERN_DEBUG "klips_debug:_aes_set_key:"
125                                 "ret=%d key_e=%p key=%p keysize=%ld\n",
126                                 ret, key_e, key, (unsigned long int) keysize);
127         return ret;
128 }
129
130 static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
131                             __u8 * in, int ilen, __u8 * iv,
132                             int encrypt)
133 {
134         AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
135         if (debug_aes > 0)
136                 printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
137                                 "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
138                                 key_e, in, ilen, iv, encrypt);
139         return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
140 }
141 #if CONFIG_KLIPS_ENC_AES_MAC
142 static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
143         aes_context_mac *ctxm=(aes_context_mac *)key_a;
144         return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
145 }
146 static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
147         int ret;
148         char hash_buf[16];
149         aes_context_mac *ctxm=(aes_context_mac *)key_a;
150         ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
151         memcpy(hash, hash_buf, hashlen);
152         return ret;
153 }
154 static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
155         ixt_common: { ixt_version:      IPSEC_ALG_VERSION,
156                       ixt_refcnt:       ATOMIC_INIT(0),
157                       ixt_name:         "aes_mac",
158                       ixt_blocksize:    ESP_AES_MAC_BLK_LEN,
159                       ixt_support: {
160                         ias_exttype:    IPSEC_ALG_TYPE_AUTH,
161                         ias_id:         0,
162                         ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
163                         ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
164                 },
165         },
166 #if defined(CONFIG_KLIPS_ENC_AES_MODULE)
167         ixt_module:     THIS_MODULE,
168 #endif
169         ixt_a_keylen:   ESP_AES_MAC_KEY_SZ,
170         ixt_a_ctx_size: sizeof(aes_context_mac),
171         ixt_a_hmac_set_key:     _aes_mac_set_key,
172         ixt_a_hmac_hash:_aes_mac_hash,
173 };
174 #endif /* CONFIG_KLIPS_ENC_AES_MAC */
175 static struct ipsec_alg_enc ipsec_alg_AES = {
176         ixt_common: { ixt_version:      IPSEC_ALG_VERSION,
177                       ixt_refcnt:       ATOMIC_INIT(0),
178                       ixt_name:         "aes",
179                       ixt_blocksize:    ESP_AES_CBC_BLK_LEN, 
180                       ixt_support: {
181                         ias_exttype:    IPSEC_ALG_TYPE_ENCRYPT,
182                         //ias_ivlen:      128,
183                         ias_id:         ESP_AES,
184                         ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
185                         ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
186                 },
187         },
188 #if defined(CONFIG_KLIPS_ENC_AES_MODULE)
189         ixt_module:     THIS_MODULE,
190 #endif
191         ixt_e_keylen:   ESP_AES_KEY_SZ_MAX,
192         ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
193         ixt_e_set_key:  _aes_set_key,
194         ixt_e_cbc_encrypt:_aes_cbc_encrypt,
195 };
196
197 #if defined(CONFIG_KLIPS_ENC_AES_MODULE)
198 IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
199 #else
200 IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
201 #endif
202 {
203         int ret, test_ret;
204
205         if (keyminbits)
206                 ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
207         if (keymaxbits) {
208                 ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
209                 if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
210                         ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
211         }
212         if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
213         ret=register_ipsec_alg_enc(&ipsec_alg_AES);
214         printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
215                         ipsec_alg_AES.ixt_common.ixt_support.ias_exttype, 
216                         ipsec_alg_AES.ixt_common.ixt_support.ias_id, 
217                         ipsec_alg_AES.ixt_common.ixt_name, 
218                         ret);
219         if (ret==0 && test_aes) {
220                 test_ret=ipsec_alg_test(
221                                 ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
222                                 ipsec_alg_AES.ixt_common.ixt_support.ias_id, 
223                                 test_aes);
224                 printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
225                                 ipsec_alg_AES.ixt_common.ixt_support.ias_exttype , 
226                                 ipsec_alg_AES.ixt_common.ixt_support.ias_id, 
227                                 test_ret);
228         }
229 #if CONFIG_KLIPS_ENC_AES_MAC
230         if (auth_id!=0){
231                 int ret;
232                 ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
233                 ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
234                 printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", 
235                                 ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype, 
236                                 ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id, 
237                                 ipsec_alg_AES_MAC.ixt_common.ixt_name, 
238                                 ret);
239                 if (ret==0 && test_aes) {
240                         test_ret=ipsec_alg_test(
241                                         ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
242                                         ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id, 
243                                         test_aes);
244                         printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", 
245                                         ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype, 
246                                         ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id, 
247                                         test_ret);
248                 }
249         } else {
250                 printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
251         }
252 #endif /* CONFIG_KLIPS_ENC_AES_MAC */
253         return ret;
254 }
255
256 #if defined(CONFIG_KLIPS_ENC_AES_MODULE)
257 IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
258 #else
259 IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
260 #endif
261 {
262 #if CONFIG_KLIPS_ENC_AES_MAC
263         if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
264 #endif /* CONFIG_KLIPS_ENC_AES_MAC */
265         unregister_ipsec_alg_enc(&ipsec_alg_AES);
266         return;
267 }
268 #ifdef MODULE_LICENSE
269 MODULE_LICENSE("GPL");
270 #endif
271
272 #if 0  /* +NOT_YET */
273 #ifndef MODULE
274 /*
275  *      This is intended for static module setups, currently
276  *      doesn't work for modular ipsec.o with static algos inside
277  */
278 static int setup_keybits(const char *str)
279 {
280         unsigned aux;
281         char *end;
282
283         aux = simple_strtoul(str,&end,0);
284         if (aux != 128 && aux != 192 && aux != 256)
285                 return 0;
286         keyminbits = aux;
287
288         if (*end == 0 || *end != ',')
289                 return 1;
290         str=end+1;
291         aux = simple_strtoul(str, NULL, 0);
292         if (aux != 128 && aux != 192 && aux != 256)
293                 return 0;
294         if (aux >= keyminbits)
295                 keymaxbits = aux;
296         return 1;
297 }
298 __setup("ipsec_aes_keybits=", setup_keybits);
299 #endif
300 #endif
301