Back to index

lightning-sunbird  0.9+nobinonly
sha_fast.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is SHA 180-1 Reference Implementation (Optimized).
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Paul Kocher of Cryptography Research.
00018  * Portions created by the Initial Developer are Copyright (C) 1995-9
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifndef _SHA_FAST_H_
00038 #define _SHA_FAST_H_
00039 
00040 #include "prlong.h"
00041 
00042 #define SHA1_INPUT_LEN 64
00043 
00044 #if defined(IS_64) && !defined(__sparc) 
00045 typedef PRUint64 SHA_HW_t;
00046 #define SHA1_USING_64_BIT 1
00047 #else
00048 typedef PRUint32 SHA_HW_t;
00049 #endif
00050 
00051 struct SHA1ContextStr {
00052   union {
00053     PRUint32 w[16];         /* input buffer */
00054     PRUint8  b[64];
00055   } u;
00056   PRUint64 size;            /* count of hashed bytes. */
00057   SHA_HW_t H[22];           /* 5 state variables, 16 tmp values, 1 extra */
00058 };
00059 
00060 #if defined(_MSC_VER) && defined(_X86_)
00061 #if defined(IS_LITTLE_ENDIAN) 
00062 #ifndef FORCEINLINE
00063 #if (_MSC_VER >= 1200)
00064 #define FORCEINLINE __forceinline
00065 #else
00066 #define FORCEINLINE __inline
00067 #endif /* _MSC_VER */
00068 #endif /* !defined FORCEINLINE */
00069 #define FASTCALL __fastcall
00070 
00071 static FORCEINLINE PRUint32 FASTCALL 
00072 swap4b(PRUint32 dwd) 
00073 {
00074     __asm {
00075        mov   eax,dwd
00076        bswap eax
00077     }
00078 }
00079 
00080 #define SHA_HTONL(x) swap4b(x)
00081 #endif /* IS_LITTLE_ENDIAN */
00082 
00083 #pragma intrinsic (_lrotr, _lrotl) 
00084 #define SHA_ROTL(x,n) _lrotl(x,n)
00085 #define SHA_ROTL_IS_DEFINED 1
00086 #endif /* _MSC_VER && _X86_ */
00087 
00088 #if defined(__GNUC__) 
00089 /* __x86_64__  and __x86_64 are defined by GCC on x86_64 CPUs */
00090 
00091 #if defined( SHA1_USING_64_BIT )
00092 static __inline__ PRUint64 SHA_ROTL(PRUint64 x, PRUint32 n)
00093 {
00094     PRUint32 t = (PRUint32)x;
00095     return ((t << n) | (t >> (32 - n)));
00096 }
00097 #else 
00098 static __inline__ PRUint32 SHA_ROTL(PRUint32 t, PRUint32 n)
00099 {
00100     return ((t << n) | (t >> (32 - n)));
00101 }
00102 #endif
00103 #define SHA_ROTL_IS_DEFINED 1
00104 
00105 #if defined(_X86_) || defined(__x86_64__) || defined(__x86_64) 
00106 static __inline__ PRUint32 swap4b(PRUint32 value)
00107 {
00108     __asm__("bswap %0" : "+r" (value));
00109     return (value);
00110 }
00111 #define SHA_HTONL(x) swap4b(x)
00112 #endif /* x86 family */
00113 
00114 #endif /* __GNUC__ */
00115 
00116 #if !defined(SHA_ROTL_IS_DEFINED)
00117 #define SHA_NEED_TMP_VARIABLE 1
00118 #define SHA_ROTL(X,n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32-(n))))
00119 #endif
00120 
00121 #if defined(_X86_) || defined(__x86_64__) || defined(__x86_64) 
00122 #define SHA_ALLOW_UNALIGNED_ACCESS 1
00123 #endif
00124 
00125 #if !defined(SHA_HTONL)
00126 #define SHA_MASK      0x00FF00FF
00127 #if defined(IS_LITTLE_ENDIAN)
00128 #undef  SHA_NEED_TMP_VARIABLE 
00129 #define SHA_NEED_TMP_VARIABLE 1
00130 #define SHA_HTONL(x)  (tmp = (x), tmp = (tmp << 16) | (tmp >> 16), \
00131                        ((tmp & SHA_MASK) << 8) | ((tmp >> 8) & SHA_MASK))
00132 #else
00133 #define SHA_HTONL(x)  (x)
00134 #endif
00135 #endif
00136 
00137 #define SHA_BYTESWAP(x) x = SHA_HTONL(x)
00138 
00139 #define SHA_STORE(n) ((PRUint32*)hashout)[n] = SHA_HTONL(ctx->H[n])
00140 #if defined(SHA_ALLOW_UNALIGNED_ACCESS)
00141 #define SHA_STORE_RESULT \
00142   SHA_STORE(0); \
00143   SHA_STORE(1); \
00144   SHA_STORE(2); \
00145   SHA_STORE(3); \
00146   SHA_STORE(4);
00147 
00148 #elif defined(IS_LITTLE_ENDIAN) || defined( SHA1_USING_64_BIT )
00149 #define SHA_STORE_RESULT \
00150   if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
00151     SHA_STORE(0); \
00152     SHA_STORE(1); \
00153     SHA_STORE(2); \
00154     SHA_STORE(3); \
00155     SHA_STORE(4); \
00156   } else { \
00157     ctx->u.w[0] = SHA_HTONL(ctx->H[0]); \
00158     ctx->u.w[1] = SHA_HTONL(ctx->H[1]); \
00159     ctx->u.w[2] = SHA_HTONL(ctx->H[2]); \
00160     ctx->u.w[3] = SHA_HTONL(ctx->H[3]); \
00161     ctx->u.w[4] = SHA_HTONL(ctx->H[4]); \
00162     memcpy(hashout, ctx->u.w, SHA1_LENGTH); \
00163   }
00164 
00165 #else
00166 #define SHA_STORE_RESULT \
00167   if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
00168     SHA_STORE(0); \
00169     SHA_STORE(1); \
00170     SHA_STORE(2); \
00171     SHA_STORE(3); \
00172     SHA_STORE(4); \
00173   } else { \
00174     memcpy(hashout, ctx->H, SHA1_LENGTH); \
00175   }
00176 #endif 
00177 
00178 #endif /* _SHA_FAST_H_ */