You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pscrypto.h 20KB

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