#include "suricata-common.h"
#include "suricata.h"
#include "util-crypt.h"
-#ifdef HAVE_NSS
-#include <sechash.h>
-#endif
-
-#ifndef HAVE_NSS
-
-#define F0(x,y,z) (z ^ (x & (y ^ z)))
-#define F1(x,y,z) (x ^ y ^ z)
-#define F2(x,y,z) ((x & y) | (z & (x | y)))
-#define F3(x,y,z) (x ^ y ^ z)
-
-
-static int Sha1Compress(HashState *md, unsigned char *buf)
-{
- uint32_t a,b,c,d,e,W[80],i;
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32H(W[i], buf + (4*i));
- }
-
- /* copy state */
- a = md->sha1.state[0];
- b = md->sha1.state[1];
- c = md->sha1.state[2];
- d = md->sha1.state[3];
- e = md->sha1.state[4];
-
- /* expand it */
- for (i = 16; i < 80; i++) {
- W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
- }
-
- /* compress */
- /* round one */
- #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
- #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
- #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
- #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
-
- for (i = 0; i < 20; ) {
- FF0(a,b,c,d,e,i++);
- FF0(e,a,b,c,d,i++);
- FF0(d,e,a,b,c,i++);
- FF0(c,d,e,a,b,i++);
- FF0(b,c,d,e,a,i++);
- }
-
- /* round two */
- for (; i < 40; ) {
- FF1(a,b,c,d,e,i++);
- FF1(e,a,b,c,d,i++);
- FF1(d,e,a,b,c,i++);
- FF1(c,d,e,a,b,i++);
- FF1(b,c,d,e,a,i++);
- }
-
- /* round three */
- for (; i < 60; ) {
- FF2(a,b,c,d,e,i++);
- FF2(e,a,b,c,d,i++);
- FF2(d,e,a,b,c,i++);
- FF2(c,d,e,a,b,i++);
- FF2(b,c,d,e,a,i++);
- }
-
- /* round four */
- for (; i < 80; ) {
- FF3(a,b,c,d,e,i++);
- FF3(e,a,b,c,d,i++);
- FF3(d,e,a,b,c,i++);
- FF3(c,d,e,a,b,i++);
- FF3(b,c,d,e,a,i++);
- }
-
- #undef FF0
- #undef FF1
- #undef FF2
- #undef FF3
-
- /* store */
- md->sha1.state[0] = md->sha1.state[0] + a;
- md->sha1.state[1] = md->sha1.state[1] + b;
- md->sha1.state[2] = md->sha1.state[2] + c;
- md->sha1.state[3] = md->sha1.state[3] + d;
- md->sha1.state[4] = md->sha1.state[4] + e;
-
- return SC_SHA_1_OK;
-}
-
-static int Sha1Init(HashState * md)
-{
- if(md == NULL)
- {
- return SC_SHA_1_NOK;
- }
- md->sha1.state[0] = 0x67452301UL;
- md->sha1.state[1] = 0xefcdab89UL;
- md->sha1.state[2] = 0x98badcfeUL;
- md->sha1.state[3] = 0x10325476UL;
- md->sha1.state[4] = 0xc3d2e1f0UL;
- md->sha1.curlen = 0;
- md->sha1.length = 0;
- return SC_SHA_1_OK;
-}
-
-static int Sha1Process (HashState * md, const unsigned char *in, unsigned long inlen)
-{
- if(md == NULL || in == NULL) {
- return SC_SHA_1_INVALID_ARG;
- }
-
- unsigned long n;
- int err;
-
- if (md->sha1.curlen > sizeof(md->sha1.buf)) {
- return SC_SHA_1_INVALID_ARG;
- }
- while (inlen > 0) {
- if (md-> sha1.curlen == 0 && inlen >= 64) {
- if ((err = Sha1Compress(md, (unsigned char *)in)) != SC_SHA_1_OK) {
- return err;
- }
- md-> sha1 .length += 64 * 8;
- in += 64;
- inlen -= 64;
- } else {
- n = MIN(inlen, (64 - md-> sha1 .curlen));
- memcpy(md-> sha1 .buf + md-> sha1.curlen, in, (size_t)n);
- md-> sha1 .curlen += n;
- in += n;
- inlen -= n;
- if (md-> sha1 .curlen == 64) {
- if ((err = Sha1Compress(md, md-> sha1 .buf)) != SC_SHA_1_OK) {
- return err;
- }
- md-> sha1 .length += 8*64;
- md-> sha1 .curlen = 0;
- }
- }
- }
- return SC_SHA_1_OK;
-}
-
-
-
-static int Sha1Done(HashState * md, unsigned char *out)
-{
- int i;
-
- if (md == NULL || out == NULL)
- {
- return SC_SHA_1_NOK;
- }
-
- if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
- return SC_SHA_1_INVALID_ARG;
- }
-
- /* increase the length of the message */
- md->sha1.length += md->sha1.curlen * 8;
-
- /* append the '1' bit */
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
-
- /* if the length is currently above 56 bytes we append zeros
- * then compress. Then we can fall back to padding zeros and length
- * encoding like normal.
- */
- if (md->sha1.curlen > 56) {
- while (md->sha1.curlen < 64) {
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
- }
- Sha1Compress(md, md->sha1.buf);
- md->sha1.curlen = 0;
- }
-
- /* pad upto 56 bytes of zeroes */
- while (md->sha1.curlen < 56) {
- md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
- }
-
- /* store length */
- STORE64H(md->sha1.length, md->sha1.buf+56);
- Sha1Compress(md, md->sha1.buf);
-
- /* copy output */
- for (i = 0; i < 5; i++) {
- STORE32H(md->sha1.state[i], out+(4*i));
- }
-
- memset(md, 0, sizeof(HashState));
-
- return SC_SHA_1_OK;
-}
-
-/** \brief calculate SHA1 hash
- * \retval int 1 for success, 0 for fail
- */
-int ComputeSHA1(const uint8_t *inbuf, size_t inbuf_len,
- uint8_t *outbuf, size_t outbuf_size)
-{
- if (unlikely(outbuf_size != 20))
- return 0;
-
- HashState md;
- Sha1Init(&md);
- Sha1Process(&md, inbuf, inbuf_len);
- Sha1Done(&md, outbuf);
- return 1;
-}
-
-#else /* HAVE_NSS */
-
-/** \brief calculate SHA1 hash
- * \retval int 1 for success, 0 for fail
- */
-int ComputeSHA1(const uint8_t *inbuf, size_t inbuf_len,
- uint8_t *outbuf, size_t outbuf_size)
-{
- if (unlikely(outbuf_size != 20))
- return 0;
-
- HASHContext *sha1_ctx = HASH_Create(HASH_AlgSHA1);
- if (sha1_ctx == NULL) {
- return 0;
- }
-
- HASH_Begin(sha1_ctx);
- HASH_Update(sha1_ctx, inbuf, inbuf_len);
- unsigned int rlen;
- HASH_End(sha1_ctx, outbuf, &rlen, outbuf_size);
- HASH_Destroy(sha1_ctx);
-
- return rlen == outbuf_size;
-}
-
-#endif /* HAVE_NSS */
static const char *b64codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define BASE64_BUFFER_SIZE(x) ((4 * ((x) + 2) / 3) + 1)
typedef enum {
- SC_SHA_1_OK,
- SC_SHA_1_NOK,
- SC_SHA_1_INVALID_ARG,
-
SC_BASE64_OK,
SC_BASE64_INVALID_ARG,
SC_BASE64_OVERFLOW,
} CryptId;
-#ifndef HAVE_NSS
-
-#define SHA1_LENGTH 20
-
-#define LOAD32H(x, y) \
- { x = ((unsigned long)((y)[0] & 255)<<24) | \
- ((unsigned long)((y)[1] & 255)<<16) | \
- ((unsigned long)((y)[2] & 255)<<8) | \
- ((unsigned long)((y)[3] & 255)); }
-
-#define STORE64H(x, y) \
- { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
- (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
- (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
- (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
-
-#define STORE32H(x, y) \
- { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
- (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
-
-#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
-#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
-#ifndef MIN
-#define MIN(x, y) ( ((x)<(y))?(x):(y) )
-#endif
-
-typedef struct Sha1State_ {
- uint64_t length;
- uint32_t state[5], curlen;
- unsigned char buf[64];
-} Sha1State;
-
-typedef union HashState_ {
- char dummy[1];
- Sha1State sha1;
- void *data;
-} HashState;
-
-#endif /* don't HAVE_NSS */
-
-int ComputeSHA1(const uint8_t * inbuf, size_t inbuf_len,
- uint8_t *outbuf, size_t outbuf_len);
int Base64Encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen);
#endif /* UTIL_CRYPT_H_ */