[mtnic] Add multiport support and some minor fixes
[people/lynusvaz/gpxe.git] / src / crypto / matrixssl / pscrypto.h
1 /*\r
2  *      pscrypto.h\r
3  *      Release $Name$\r
4  *\r
5  *      Internal definitions for PeerSec Networks MatrixSSL cryptography provider\r
6  */\r
7 /*\r
8  *      Copyright (c) PeerSec Networks, 2002-2006. All Rights Reserved.\r
9  *      The latest version of this code is available at http://www.matrixssl.org\r
10  *\r
11  *      This software is open source; you can redistribute it and/or modify\r
12  *      it under the terms of the GNU General Public License as published by\r
13  *      the Free Software Foundation; either version 2 of the License, or\r
14  *      (at your option) any later version.\r
15  *\r
16  *      This General Public License does NOT permit incorporating this software \r
17  *      into proprietary programs.  If you are unable to comply with the GPL, a \r
18  *      commercial license for this software may be purchased from PeerSec Networks\r
19  *      at http://www.peersec.com\r
20  *      \r
21  *      This program is distributed in WITHOUT ANY WARRANTY; without even the \r
22  *      implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \r
23  *      See the GNU General Public License for more details.\r
24  *      \r
25  *      You should have received a copy of the GNU General Public License\r
26  *      along with this program; if not, write to the Free Software\r
27  *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
28  *      http://www.gnu.org/copyleft/gpl.html\r
29  */\r
30 /******************************************************************************/\r
31 \r
32 #ifndef _h_PSCRYPTO\r
33 #define _h_PSCRYPTO\r
34 \r
35 #ifdef __cplusplus\r
36 extern "C" {\r
37 #endif\r
38 \r
39 /*\r
40         PeerSec crypto-specific defines.\r
41  */\r
42 #define SMALL_CODE\r
43 #define CLEAN_STACK\r
44 /*\r
45         If Native 64 bit integers are not supported, we must set the 16 bit flag\r
46         to produce 32 bit mp_words in mpi.h\r
47         We must also include the slow MPI functions because the fast ones only\r
48         work with larger (28 bit) digit sizes.\r
49 */\r
50 #ifndef USE_INT64\r
51 #define MP_16BIT\r
52 #define USE_SMALL_WORD\r
53 #endif /* USE_INT64 */\r
54 \r
55 /******************************************************************************/\r
56 \r
57 #ifdef USE_RSA\r
58 \r
59 #include "mpi.h"\r
60 \r
61 #if LINUX\r
62         #define _stat stat\r
63 #endif\r
64 \r
65 /* this is the "32-bit at least" data type \r
66  * Re-define it to suit your platform but it must be at least 32-bits \r
67  */\r
68 typedef unsigned long ulong32;\r
69 \r
70 /*\r
71         Primary RSA Key struct.  Define here for crypto\r
72 */\r
73 typedef struct {\r
74         mp_int          e, d, N, qP, dP, dQ, p, q;\r
75         int32                   size;   /* Size of the key in bytes */\r
76         int32                   optimized; /* 1 for optimized */\r
77 } sslRsaKey_t;\r
78 \r
79 #endif /* USE_RSA */\r
80 \r
81 \r
82 /*\r
83  *      Private\r
84  */\r
85 extern int32 ps_base64_decode(const unsigned char *in, uint32 len, \r
86                                                         unsigned char *out, uint32 *outlen);\r
87 \r
88 /*\r
89  *      Memory routines\r
90  */\r
91 extern void psZeromem(void *dst, size_t len);\r
92 extern void psBurnStack(unsigned long len);\r
93 \r
94 \r
95 /* max size of either a cipher/hash block or symmetric key [largest of the two] */\r
96 #define MAXBLOCKSIZE                    24\r
97 \r
98 /* ch1-01-1 */\r
99 /* error codes [will be expanded in future releases] */\r
100 enum {\r
101         CRYPT_OK=0,                                     /* Result OK */\r
102         CRYPT_ERROR,                            /* Generic Error */\r
103         CRYPT_NOP,                                      /* Not a failure but no operation was performed */\r
104 \r
105         CRYPT_INVALID_KEYSIZE,          /* Invalid key size given */\r
106         CRYPT_INVALID_ROUNDS,           /* Invalid number of rounds */\r
107         CRYPT_FAIL_TESTVECTOR,          /* Algorithm failed test vectors */\r
108 \r
109         CRYPT_BUFFER_OVERFLOW,          /* Not enough space for output */\r
110         CRYPT_INVALID_PACKET,           /* Invalid input packet given */\r
111 \r
112         CRYPT_INVALID_PRNGSIZE,         /* Invalid number of bits for a PRNG */\r
113         CRYPT_ERROR_READPRNG,           /* Could not read enough from PRNG */\r
114 \r
115         CRYPT_INVALID_CIPHER,           /* Invalid cipher specified */\r
116         CRYPT_INVALID_HASH,                     /* Invalid hash specified */\r
117         CRYPT_INVALID_PRNG,                     /* Invalid PRNG specified */\r
118 \r
119         CRYPT_MEM,                                      /* Out of memory */\r
120 \r
121         CRYPT_PK_TYPE_MISMATCH,         /* Not equivalent types of PK keys */\r
122         CRYPT_PK_NOT_PRIVATE,           /* Requires a private PK key */\r
123 \r
124         CRYPT_INVALID_ARG,                      /* Generic invalid argument */\r
125         CRYPT_FILE_NOTFOUND,            /* File Not Found */\r
126 \r
127         CRYPT_PK_INVALID_TYPE,          /* Invalid type of PK key */\r
128         CRYPT_PK_INVALID_SYSTEM,        /* Invalid PK system specified */\r
129         CRYPT_PK_DUP,                           /* Duplicate key already in key ring */\r
130         CRYPT_PK_NOT_FOUND,                     /* Key not found in keyring */\r
131         CRYPT_PK_INVALID_SIZE,          /* Invalid size input for PK parameters */\r
132 \r
133         CRYPT_INVALID_PRIME_SIZE        /* Invalid size of prime requested */\r
134 };\r
135 \r
136 /******************************************************************************/\r
137 /*\r
138         hash defines\r
139  */\r
140 struct sha1_state {\r
141 #ifdef USE_INT64\r
142         ulong64         length;\r
143 #else\r
144         ulong32         lengthHi;\r
145         ulong32         lengthLo;\r
146 #endif /* USE_INT64 */\r
147         ulong32 state[5], curlen;\r
148         unsigned char   buf[64];\r
149 };\r
150 \r
151 struct md5_state {\r
152 #ifdef USE_INT64\r
153         ulong64 length;\r
154 #else\r
155         ulong32 lengthHi;\r
156         ulong32 lengthLo;\r
157 #endif /* USE_INT64 */\r
158         ulong32 state[4], curlen;\r
159         unsigned char buf[64];\r
160 };\r
161 \r
162 #ifdef USE_MD2\r
163 struct md2_state {\r
164         unsigned char chksum[16], X[48], buf[16];\r
165         unsigned long curlen;\r
166 };\r
167 #endif /* USE_MD2 */\r
168 \r
169 #ifdef USE_SHA256\r
170 struct sha256_state {\r
171         ulong64 length;\r
172         ulong32 state[8], curlen;\r
173         unsigned char buf[64];\r
174 };\r
175 #endif /* USE_SHA256 */\r
176 \r
177 typedef union {\r
178         struct sha1_state       sha1;\r
179         struct md5_state        md5;\r
180 #ifdef USE_MD2\r
181         struct md2_state        md2;\r
182 #endif /* USE_MD2 */\r
183 #ifdef USE_SHA256\r
184         struct sha256_state sha256;\r
185 #endif\r
186 } hash_state;\r
187 \r
188 typedef hash_state sslSha1Context_t;\r
189 typedef hash_state sslMd5Context_t;\r
190 #ifdef USE_MD2\r
191 typedef hash_state sslMd2Context_t;\r
192 #endif /* USE_MD2 */\r
193 #ifdef USE_SHA256\r
194 typedef hash_state sslSha256Context_t;\r
195 #endif /* USE_SHA256 */\r
196 \r
197 typedef struct {\r
198         unsigned char   pad[64];\r
199         union {\r
200                 sslMd5Context_t         md5;\r
201                 sslSha1Context_t        sha1;\r
202         } u;\r
203 } sslHmacContext_t;\r
204 \r
205 /******************************************************************************/\r
206 /*\r
207         RC4\r
208  */\r
209 #ifdef USE_ARC4\r
210 typedef struct {\r
211         unsigned char   state[256];\r
212         uint32  byteCount;\r
213         unsigned char   x;\r
214         unsigned char   y;\r
215 } rc4_key;\r
216 #endif /* USE_ARC4 */\r
217 \r
218 #define SSL_DES3_KEY_LEN        24\r
219 #define SSL_DES3_IV_LEN         8\r
220 #ifdef USE_3DES\r
221 \r
222 typedef struct {\r
223         ulong32 ek[3][32], dk[3][32];\r
224 } des3_key;\r
225 \r
226 /*\r
227         A block cipher CBC structure\r
228  */\r
229 typedef struct {\r
230         int32                                   blocklen;\r
231         unsigned char           IV[8];\r
232         des3_key                        key;\r
233         int32                                   explicitIV; /* 1 if yes */\r
234 } des3_CBC;\r
235 \r
236 extern int32 des3_setup(const unsigned char *key, int32 keylen, int32 num_rounds,\r
237                  des3_CBC *skey);\r
238 extern void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct,\r
239                  des3_CBC *key);\r
240 extern void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt,\r
241                  des3_CBC *key);\r
242 extern int32 des3_keysize(int32 *desired_keysize);\r
243 \r
244 extern int32 des_setup(const unsigned char *key, int32 keylen, int32 num_rounds,\r
245                  des3_CBC *skey);\r
246 extern void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct,\r
247                  des3_CBC *key);\r
248 extern void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt,\r
249                  des3_CBC *key);\r
250 \r
251 #endif /* USE_3DES */\r
252 \r
253 \r
254 typedef union {\r
255 #ifdef USE_ARC4\r
256         rc4_key         arc4;\r
257 #endif\r
258 #ifdef USE_3DES\r
259         des3_CBC        des3;\r
260 #endif\r
261 } sslCipherContext_t;\r
262 \r
263 \r
264 /*\r
265         Controls endianess and size of registers.  Leave uncommented to get\r
266         platform neutral [slower] code detect x86-32 machines somewhat\r
267  */\r
268 #if (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))\r
269         #define ENDIAN_LITTLE\r
270         #define ENDIAN_32BITWORD\r
271 #endif\r
272 \r
273 \r
274 /* #define ENDIAN_LITTLE */\r
275 /* #define ENDIAN_BIG */\r
276 \r
277 /* #define ENDIAN_32BITWORD */\r
278 /* #define ENDIAN_64BITWORD */\r
279 \r
280 #if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))\r
281                 #error You must specify a word size as well as endianess\r
282 #endif\r
283 \r
284 #if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))\r
285         #define ENDIAN_NEUTRAL\r
286 #endif\r
287 \r
288 /*\r
289         helper macros\r
290  */\r
291 #if defined (ENDIAN_NEUTRAL)\r
292 \r
293 #define STORE32L(x, y)                                                                     \\r
294      { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \\r
295        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }\r
296 \r
297 #define LOAD32L(x, y)                            \\r
298      { x = ((unsigned long)((y)[3] & 255)<<24) | \\r
299            ((unsigned long)((y)[2] & 255)<<16) | \\r
300            ((unsigned long)((y)[1] & 255)<<8)  | \\r
301            ((unsigned long)((y)[0] & 255)); }\r
302 \r
303 #define STORE64L(x, y)                                                                     \\r
304      { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \\r
305        (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \\r
306        (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \\r
307        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }\r
308 \r
309 #define LOAD64L(x, y)                                                       \\r
310      { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \\r
311            (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \\r
312            (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \\r
313            (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }\r
314 \r
315 #define STORE32H(x, y)                                                                     \\r
316      { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \\r
317        (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }\r
318 \r
319 #define LOAD32H(x, y)                            \\r
320      { x = ((unsigned long)((y)[0] & 255)<<24) | \\r
321            ((unsigned long)((y)[1] & 255)<<16) | \\r
322            ((unsigned long)((y)[2] & 255)<<8)  | \\r
323            ((unsigned long)((y)[3] & 255)); }\r
324 \r
325 #define STORE64H(x, y)                                                                     \\r
326    { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \\r
327      (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \\r
328      (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \\r
329      (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }\r
330 \r
331 #define LOAD64H(x, y)                                                      \\r
332    { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \\r
333          (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \\r
334          (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \\r
335          (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }\r
336 \r
337 #endif /* ENDIAN_NEUTRAL */\r
338 \r
339 #ifdef ENDIAN_LITTLE\r
340 \r
341 #define STORE32H(x, y)                                                                     \\r
342      { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \\r
343        (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }\r
344 \r
345 #define LOAD32H(x, y)                            \\r
346      { x = ((unsigned long)((y)[0] & 255)<<24) | \\r
347            ((unsigned long)((y)[1] & 255)<<16) | \\r
348            ((unsigned long)((y)[2] & 255)<<8)  | \\r
349            ((unsigned long)((y)[3] & 255)); }\r
350 \r
351 #define STORE64H(x, y)                                                                     \\r
352    { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \\r
353      (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \\r
354      (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \\r
355      (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }\r
356 \r
357 #define LOAD64H(x, y)                                                      \\r
358    { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \\r
359          (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \\r
360          (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \\r
361          (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }\r
362 \r
363 #ifdef ENDIAN_32BITWORD \r
364 \r
365 #define STORE32L(x, y)        \\r
366      { unsigned long __t = (x); memcpy(y, &__t, 4); }\r
367 \r
368 #define LOAD32L(x, y)         \\r
369      memcpy(&(x), y, 4);\r
370 \r
371 #define STORE64L(x, y)                                                                     \\r
372      { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \\r
373        (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \\r
374        (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \\r
375        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }\r
376 \r
377 #define LOAD64L(x, y)                                                       \\r
378      { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \\r
379            (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \\r
380            (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \\r
381            (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }\r
382 \r
383 #else /* 64-bit words then  */\r
384 \r
385 #define STORE32L(x, y)        \\r
386      { unsigned long __t = (x); memcpy(y, &__t, 4); }\r
387 \r
388 #define LOAD32L(x, y)         \\r
389      { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }\r
390 \r
391 #define STORE64L(x, y)        \\r
392      { ulong64 __t = (x); memcpy(y, &__t, 8); }\r
393 \r
394 #define LOAD64L(x, y)         \\r
395     { memcpy(&(x), y, 8); }\r
396 \r
397 #endif /* ENDIAN_64BITWORD */\r
398 #endif /* ENDIAN_LITTLE */\r
399 \r
400 #ifdef ENDIAN_BIG\r
401 #define STORE32L(x, y)                                                                     \\r
402      { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \\r
403        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }\r
404 \r
405 #define LOAD32L(x, y)                            \\r
406      { x = ((unsigned long)((y)[3] & 255)<<24) | \\r
407            ((unsigned long)((y)[2] & 255)<<16) | \\r
408            ((unsigned long)((y)[1] & 255)<<8)  | \\r
409            ((unsigned long)((y)[0] & 255)); }\r
410 \r
411 #define STORE64L(x, y)                                                                     \\r
412    { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \\r
413      (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \\r
414      (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \\r
415      (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }\r
416 \r
417 #define LOAD64L(x, y)                                                      \\r
418    { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \\r
419          (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \\r
420          (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \\r
421          (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }\r
422 \r
423 #ifdef ENDIAN_32BITWORD \r
424 \r
425 #define STORE32H(x, y)        \\r
426      { unsigned long __t = (x); memcpy(y, &__t, 4); }\r
427 \r
428 #define LOAD32H(x, y)         \\r
429      memcpy(&(x), y, 4);\r
430 \r
431 #define STORE64H(x, y)                                                                     \\r
432      { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \\r
433        (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \\r
434        (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \\r
435        (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }\r
436 \r
437 #define LOAD64H(x, y)                                                       \\r
438      { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \\r
439            (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \\r
440            (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \\r
441            (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }\r
442 \r
443 #else /* 64-bit words then  */\r
444 \r
445 #define STORE32H(x, y)        \\r
446      { unsigned long __t = (x); memcpy(y, &__t, 4); }\r
447 \r
448 #define LOAD32H(x, y)         \\r
449      { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }\r
450 \r
451 #define STORE64H(x, y)        \\r
452      { ulong64 __t = (x); memcpy(y, &__t, 8); }\r
453 \r
454 #define LOAD64H(x, y)         \\r
455     { memcpy(&(x), y, 8); }\r
456 \r
457 #endif /* ENDIAN_64BITWORD */\r
458 #endif /* ENDIAN_BIG */\r
459 \r
460 /*\r
461         packet code */\r
462 #if defined(USE_RSA) || defined(MDH) || defined(MECC)\r
463         #define PACKET\r
464 \r
465 /*\r
466         size of a packet header in bytes */\r
467         #define PACKET_SIZE                             4\r
468 \r
469 /*\r
470         Section tags\r
471  */\r
472         #define PACKET_SECT_RSA                 0\r
473         #define PACKET_SECT_DH                  1\r
474         #define PACKET_SECT_ECC                 2\r
475         #define PACKET_SECT_DSA                 3\r
476 \r
477 /*\r
478         Subsection Tags for the first three sections\r
479  */\r
480         #define PACKET_SUB_KEY                  0\r
481         #define PACKET_SUB_ENCRYPTED    1\r
482         #define PACKET_SUB_SIGNED               2\r
483         #define PACKET_SUB_ENC_KEY              3\r
484 #endif\r
485 \r
486 /*\r
487         fix for MSVC ...evil!\r
488  */\r
489 #ifdef WIN32\r
490 #ifdef _MSC_VER\r
491         #define CONST64(n) n ## ui64\r
492         typedef unsigned __int64 ulong64;\r
493 #else\r
494         #define CONST64(n) n ## ULL\r
495         typedef unsigned long long ulong64;\r
496 #endif\r
497 #endif /* WIN32 */\r
498 \r
499 \r
500 #define BSWAP(x)  ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL)  | \\r
501                     ((x>>8)&0x0000FF00UL)  | ((x<<8)&0x00FF0000UL) )\r
502 \r
503 #ifdef _MSC_VER\r
504 \r
505 /*\r
506         instrinsic rotate\r
507  */\r
508 #include <stdlib.h>\r
509 #pragma intrinsic(_lrotr,_lrotl)\r
510 #define ROR(x,n) _lrotr(x,n)\r
511 #define ROL(x,n) _lrotl(x,n)\r
512 #define RORc(x,n) _lrotr(x,n)\r
513 #define ROLc(x,n) _lrotl(x,n)\r
514 \r
515 /*\r
516 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(PS_NO_ASM)\r
517 \r
518 static inline unsigned ROL(unsigned word, int32 i)\r
519 {\r
520         asm ("roll %%cl,%0"\r
521                 :"0" (word),"c" (i));\r
522         return word;\r
523 }\r
524 \r
525 static inline unsigned ROR(unsigned word, int32 i)\r
526 {\r
527         asm ("rorl %%cl,%0"\r
528                 :"=r" (word)\r
529                 :"0" (word),"c" (i));\r
530         return word;\r
531 }\r
532 */\r
533 /*\r
534 #ifndef PS_NO_ROLC\r
535 \r
536 static inline unsigned ROLc(unsigned word, const int32 i)\r
537 {\r
538    asm ("roll %2,%0"\r
539       :"=r" (word)\r
540       :"0" (word),"I" (i));\r
541    return word;\r
542 }\r
543 \r
544 static inline unsigned RORc(unsigned word, const int32 i)\r
545 {\r
546    asm ("rorl %2,%0"\r
547       :"=r" (word)\r
548       :"0" (word),"I" (i));\r
549    return word;\r
550 }\r
551 \r
552 #else\r
553 \r
554 #define ROLc ROL\r
555 #define RORc ROR\r
556 \r
557 #endif\r
558 */\r
559 \r
560 #else /* _MSC_VER */\r
561 \r
562 /*\r
563         rotates the hard way\r
564  */\r
565 #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)\r
566 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)\r
567 #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)\r
568 #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)\r
569 \r
570 #endif /* _MSC_VER */\r
571 \r
572 /* 64-bit Rotates */\r
573 #if 0\r
574 \r
575 #if defined(__GNUC__) && defined(__x86_64__) && !defined(PS_NO_ASM)\r
576 \r
577 static inline unsigned long ROL64(unsigned long word, int32 i)\r
578 {\r
579    asm("rolq %%cl,%0"\r
580       :"=r" (word)\r
581       :"0" (word),"c" (i));\r
582    return word;\r
583 }\r
584 \r
585 static inline unsigned long ROR64(unsigned long word, int32 i)\r
586 {\r
587    asm("rorq %%cl,%0"\r
588       :"=r" (word)\r
589       :"0" (word),"c" (i));\r
590    return word;\r
591 }\r
592 \r
593 #ifndef PS_NO_ROLC\r
594 \r
595 static inline unsigned long ROL64c(unsigned long word, const int32 i)\r
596 {\r
597    asm("rolq %2,%0"\r
598       :"=r" (word)\r
599       :"0" (word),"J" (i));\r
600    return word;\r
601 }\r
602 \r
603 static inline unsigned long ROR64c(unsigned long word, const int32 i)\r
604 {\r
605    asm("rorq %2,%0"\r
606       :"=r" (word)\r
607       :"0" (word),"J" (i));\r
608    return word;\r
609 }\r
610 \r
611 #else /* PS_NO_ROLC */\r
612 \r
613 #define ROL64c ROL\r
614 #define ROR64c ROR\r
615 \r
616 #endif /* PS_NO_ROLC */\r
617 #endif\r
618 #endif /* commented out */\r
619 \r
620 #define ROL64(x, y) \\r
621     ( (((x)<<((ulong64)(y)&63)) | \\r
622       (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))\r
623 \r
624 #define ROR64(x, y) \\r
625     ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \\r
626       ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))\r
627 \r
628 #define ROL64c(x, y) \\r
629     ( (((x)<<((ulong64)(y)&63)) | \\r
630       (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))\r
631 \r
632 #define ROR64c(x, y) \\r
633     ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \\r
634       ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))\r
635 \r
636 #undef MAX\r
637 #undef MIN\r
638 #define MAX(x, y) ( ((x)>(y))?(x):(y) )\r
639 #define MIN(x, y) ( ((x)<(y))?(x):(y) )\r
640 \r
641 /*\r
642         extract a byte portably This MSC code causes runtime errors in VS.NET,\r
643         always use the other\r
644  */\r
645 /*\r
646 #ifdef _MSC_VER\r
647    #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))\r
648 #else\r
649 */\r
650    #define byte(x, n) (((x) >> (8 * (n))) & 255)\r
651 /*\r
652 #endif\r
653 */\r
654 #ifdef __cplusplus\r
655    }\r
656 #endif /* __cplusplus */\r
657 \r
658 #endif /* _h_PSCRYPTO */\r
659 \r
660 /******************************************************************************/\r
661 \r