MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / char / mxhwenp / mxhw_crypto_wrapper.c
blobd0379d83e4946da589003767c4d37617c4f2e288
1 #include <fcntl.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <pthread.h>
6 #include <mxhw_crypto_userio.h>
7 #include <mxhw_crypto_wrapper.h>
9 static SSNTAB global_sessions[MAX_CIPHER_CLIENTS];
11 #define SSN_FREE 0
12 #define SSN_CREATE 1
13 #define SSN_ENCRYPT (1<<1)
14 #define SSN_DECRYPT (1<<2)
16 #define SET_SSN_FREE(s) memset(s,0,sizeof(SSNTAB))
17 #define CHK_SSN_ENCRYPT(s) (s->flag&SSN_ENCRYPT)
18 #define CHK_SSN_DECRYPT(s) (s->flag&SSN_DECRYPT)
20 #define SSNFIND(s,k) \
21 { int i; s = NULL;\
22 for (i=0; i < MAX_CIPHER_CLIENTS; i++) \
23 if (k && global_sessions[i].bkey==k) { s = &global_sessions[i]; break; } \
26 static SSNTAB*
27 mxcrypto_find(void *key)
29 SSNTAB *s;
31 SSNFIND(s,key);
32 return s;
35 SSNTAB*
36 mxcrypto_create(const void *userKey, u_int klen, void *key, u_int blen, u_int is_aes_key)
38 SSNTAB *s=NULL;
39 static int first=1;
40 int i;
42 if (first)
44 memset(global_sessions, 0, MAX_CIPHER_CLIENTS*sizeof(SSNTAB));
45 first = 0;
47 /* find a session by binary key */
48 if ((s=mxcrypto_find(key)))
49 mxcrypto_close(key);
51 for (i=0; i < MAX_CIPHER_CLIENTS; i++)
53 s = &global_sessions[i];
54 if (s->flag==SSN_FREE)
56 s->enId = s->deId = 0;
57 s->flag = SSN_CREATE;
58 s->bkey = key;
59 s->blen = blen;
60 s->klen = (is_aes_key)? (klen>>3):klen; /* bytes for both of the DES and AES */
61 memcpy(s->ukey, userKey, s->klen);
62 return s;
65 return NULL;
68 static disable_hw=0;
69 void
70 mxcrypto_set_software(int flag)
72 disable_hw = flag;
75 /*
76 This is an over-all interface performing cipher tasks for all kinds of algorithms
77 in 4/5 modes.
79 note: typeless keys and ivec to offer a maximum room for any application.
81 returns: > 0, use software approach.
82 = 0, hardware ok.
83 < 0, hardware failure.
85 int
86 mxcrypto_perfrom(u_int algo, u_int mode, const u_char *input, u_char *output, u_long length,
87 void *key1, void *key2, void *key3, void *ivec, u_int numbits, int enc)
89 SSNTAB *s;
90 int fd;
92 DBG("mxcrypto_perfrom=%d %d %lu %d\n", algo, mode, length, enc);
94 if (disable_hw)
96 DBG("SW %s\n", enc? "ENCRYPT":"DECRYPT");
97 return 1;
99 /* find a session by binary key */
100 SSNFIND(s,key1);
101 if (s==NULL)
102 return 1;
103 DBG("HW %s\n", enc? "ENCRYPT":"DECRYPT");
105 fd = (enc!=0)? s->enId:s->deId;
106 if (fd==0)
108 SSNTAB *s2=NULL, *s3=NULL;
110 DBG("--------mxcrypto_perfrom %d\n", 22);
111 if (s->flag==SSN_CREATE)
113 DBG("--------mxcrypto_perfrom %d\n", 33);
114 /* if it is triple des */
115 if (algo==MXCIPHER_ALGO_3DES)
117 if (key2==NULL || key3==NULL)
119 SET_SSN_FREE(s);
120 return 2;
122 s2 = mxcrypto_find(key2);
123 s3 = mxcrypto_find(key3);
124 if (s2==NULL || s3==NULL)
126 SET_SSN_FREE(s);
127 return 2;
129 /* put keys together */
130 memcpy(s->ukey+s->klen, s2->ukey, s2->klen);
131 s->klen += s2->klen;
132 memcpy(s->ukey+s->klen, s3->ukey, s3->klen);
133 s->klen += s3->klen;
134 DBG("--------mxcrypto_perfrom %d\n", 44);
137 if (algo==MXCIPHER_ALGO_AES)
139 int klen = s->klen<<3;
141 DBG("--------mxcrypto_perfrom aes klen %d\n", s->klen);
142 if (klen==128) algo = MXCIPHER_ALGO_AES128;
143 else if (klen==192) algo = MXCIPHER_ALGO_AES192;
144 else if (klen==256) algo = MXCIPHER_ALGO_AES256;
145 else
147 SET_SSN_FREE(s);
148 return 3;
151 /* after keys have been put together */
152 if (mode==MXCIPHER_MODE_ECB)
153 s->blen = 0;
155 DBG("--------register hardware approache=%d %d %d %d\n", algo, mode, s->blen, s->klen);
157 /* register a contexts and return a file descriptor */
158 fd = mxcrypto_uio_register(algo, mode, s->ukey, numbits, enc);
159 /* no matterwhat, free up 2 tmp sessions */
160 if (s2 && s2!=s) SET_SSN_FREE(s2);
161 if (s3 && s3!=s) SET_SSN_FREE(s3);
162 if (fd < 0)
164 SET_SSN_FREE(s);
165 return 4;
167 if (enc){ s->flag|=SSN_ENCRYPT; s->enId=fd; }
168 else { s->flag|=SSN_DECRYPT; s->deId=fd; }
171 if (mxcrypto_uio_perform(fd, input, output, length, ivec, s->blen)==0)
173 DBG("--------%s ok hardware approache=%d %d %d %d\n", enc? "ENCRYPT":"DECRYPT",
174 algo, mode, s->blen, s->klen);
175 return 0;
177 DBG("--------fial try hardware approache = %d\n", fd);
178 if (fd>0) mxcrypto_close(key1); /* since we turn hw to sw, so free it now */
179 return 5;
182 /* before free up the memory for keys, close the file */
184 mxcrypto_close(void *key)
186 SSNTAB *s = mxcrypto_find(key);
187 int size=0;
189 /* find a session by binary key */
190 if (s)
193 if (s->enId>0)
194 size += mxcrypto_uio_close(s->enId);
195 if (s->deId>0)
196 size += mxcrypto_uio_close(s->deId);
197 SET_SSN_FREE(s);
199 return size;