Commit 5126380b authored by Ondřej Zajíček's avatar Ondřej Zajíček

Minor changes to SHA hash functions

parent 12d752ef
......@@ -30,6 +30,7 @@
#define MAX(a,b) MAX_(a,b)
#endif
#define U64(c) UINT64_C(c)
#define ABS(a) ((a)>=0 ? (a) : -(a))
#define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a))
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
......
......@@ -15,33 +15,35 @@
#include "lib/sha1.h"
#include "lib/unaligned.h"
void
sha1_init(struct sha1_context *hd)
sha1_init(struct sha1_context *ctx)
{
hd->h0 = 0x67452301;
hd->h1 = 0xefcdab89;
hd->h2 = 0x98badcfe;
hd->h3 = 0x10325476;
hd->h4 = 0xc3d2e1f0;
hd->nblocks = 0;
hd->count = 0;
ctx->h0 = 0x67452301;
ctx->h1 = 0xefcdab89;
ctx->h2 = 0x98badcfe;
ctx->h3 = 0x10325476;
ctx->h4 = 0xc3d2e1f0;
ctx->nblocks = 0;
ctx->count = 0;
}
/*
* Transform the message X which consists of 16 32-bit-words
*/
static void
sha1_transform(struct sha1_context *hd, const byte *data)
sha1_transform(struct sha1_context *ctx, const byte *data)
{
u32 a,b,c,d,e,tm;
u32 x[16];
/* Get values from the chaining vars. */
a = hd->h0;
b = hd->h1;
c = hd->h2;
d = hd->h3;
e = hd->h4;
a = ctx->h0;
b = ctx->h1;
c = ctx->h2;
d = ctx->h3;
e = ctx->h4;
#ifdef CPU_BIG_ENDIAN
memcpy(x, data, 64);
......@@ -69,7 +71,7 @@ sha1_transform(struct sha1_context *hd, const byte *data)
do \
{ \
e += ROL(a, 5) + f(b, c, d) + k + m; \
b = ROL( b, 30 ); \
b = ROL(b, 30); \
} while(0)
R( a, b, c, d, e, F1, K1, x[ 0] );
......@@ -154,72 +156,72 @@ sha1_transform(struct sha1_context *hd, const byte *data)
R( b, c, d, e, a, F4, K4, M(79) );
/* Update chaining vars. */
hd->h0 += a;
hd->h1 += b;
hd->h2 += c;
hd->h3 += d;
hd->h4 += e;
ctx->h0 += a;
ctx->h1 += b;
ctx->h2 += c;
ctx->h3 += d;
ctx->h4 += e;
}
/*
* Update the message digest with the contents
* of INBUF with length INLEN.
* Update the message digest with the contents of BUF with length LEN.
*/
void
sha1_update(struct sha1_context *hd, const byte *inbuf, uint inlen)
sha1_update(struct sha1_context *ctx, const byte *buf, uint len)
{
if (hd->count == 64) /* flush the buffer */
if (ctx->count)
{
sha1_transform(hd, hd->buf);
hd->count = 0;
hd->nblocks++;
}
if (!inbuf)
return;
/* Fill rest of internal buffer */
for (; len && ctx->count < SHA1_BLOCK_SIZE; len--)
ctx->buf[ctx->count++] = *buf++;
if (hd->count)
{
for (; inlen && hd->count < 64; inlen--)
hd->buf[hd->count++] = *inbuf++;
sha1_update( hd, NULL, 0 );
if(!inlen)
if (ctx->count < SHA1_BLOCK_SIZE)
return;
/* Process data from internal buffer */
sha1_transform(ctx, ctx->buf);
ctx->nblocks++;
ctx->count = 0;
}
while (inlen >= 64)
if (!len)
return;
/* Process data from input buffer */
while (len >= SHA1_BLOCK_SIZE)
{
sha1_transform(hd, inbuf);
hd->count = 0;
hd->nblocks++;
inlen -= 64;
inbuf += 64;
sha1_transform(ctx, buf);
ctx->nblocks++;
buf += SHA1_BLOCK_SIZE;
len -= SHA1_BLOCK_SIZE;
}
for (; inlen && hd->count < 64; inlen--)
hd->buf[hd->count++] = *inbuf++;
/* Copy remaining data to internal buffer */
memcpy(ctx->buf, buf, len);
ctx->count = len;
}
/*
* The routine final terminates the computation and
* returns the digest.
* The handle is prepared for a new cycle, but adding bytes to the
* handle will the destroy the returned buffer.
* The routine final terminates the computation and returns the digest. The
* handle is prepared for a new cycle, but adding bytes to the handle will the
* destroy the returned buffer.
*
* Returns: 20 bytes representing the digest.
*/
byte *
sha1_final(struct sha1_context *hd)
sha1_final(struct sha1_context *ctx)
{
u32 t, msb, lsb;
u32 *p;
sha1_update(hd, NULL, 0); /* flush */;
sha1_update(ctx, NULL, 0); /* flush */
t = hd->nblocks;
t = ctx->nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
if ((lsb += hd->count) < t)
if ((lsb += ctx->count) < t)
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
......@@ -227,33 +229,36 @@ sha1_final(struct sha1_context *hd)
msb <<= 3;
msb |= t >> 29;
if (hd->count < 56) /* enough room */
if (ctx->count < 56)
{
hd->buf[hd->count++] = 0x80; /* pad */
while (hd->count < 56)
hd->buf[hd->count++] = 0; /* pad */
/* enough room */
ctx->buf[ctx->count++] = 0x80; /* pad */
while (ctx->count < 56)
ctx->buf[ctx->count++] = 0; /* pad */
}
else /* need one extra block */
else
{
hd->buf[hd->count++] = 0x80; /* pad character */
while (hd->count < 64)
hd->buf[hd->count++] = 0;
sha1_update(hd, NULL, 0); /* flush */;
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
/* need one extra block */
ctx->buf[ctx->count++] = 0x80; /* pad character */
while (ctx->count < 64)
ctx->buf[ctx->count++] = 0;
sha1_update(ctx, NULL, 0); /* flush */
memset(ctx->buf, 0, 56); /* fill next block with zeroes */
}
/* append the 64 bit count */
hd->buf[56] = msb >> 24;
hd->buf[57] = msb >> 16;
hd->buf[58] = msb >> 8;
hd->buf[59] = msb ;
hd->buf[60] = lsb >> 24;
hd->buf[61] = lsb >> 16;
hd->buf[62] = lsb >> 8;
hd->buf[63] = lsb ;
sha1_transform(hd, hd->buf);
p = (u32*) hd->buf;
#define X(a) do { put_u32(p, hd->h##a); p++; } while(0)
ctx->buf[56] = msb >> 24;
ctx->buf[57] = msb >> 16;
ctx->buf[58] = msb >> 8;
ctx->buf[59] = msb;
ctx->buf[60] = lsb >> 24;
ctx->buf[61] = lsb >> 16;
ctx->buf[62] = lsb >> 8;
ctx->buf[63] = lsb;
sha1_transform(ctx, ctx->buf);
byte *p = ctx->buf;
#define X(a) do { put_u32(p, ctx->h##a); p += 4; } while(0)
X(0);
X(1);
X(2);
......@@ -261,12 +266,12 @@ sha1_final(struct sha1_context *hd)
X(4);
#undef X
return hd->buf;
return ctx->buf;
}
/*
* SHA1-HMAC
* SHA1-HMAC
*/
/*
......@@ -292,12 +297,12 @@ sha1_hmac_init(struct sha1_hmac_context *ctx, const byte *key, uint keylen)
if (keylen <= SHA1_BLOCK_SIZE)
{
memcpy(keybuf, key, keylen);
bzero(keybuf + keylen, SHA1_BLOCK_SIZE - keylen);
memset(keybuf + keylen, 0, SHA1_BLOCK_SIZE - keylen);
}
else
{
sha1_hash_buffer(keybuf, key, keylen);
bzero(keybuf + SHA1_SIZE, SHA1_BLOCK_SIZE - SHA1_SIZE);
memset(keybuf + SHA1_SIZE, 0, SHA1_BLOCK_SIZE - SHA1_SIZE);
}
/* Initialize the inner digest */
......@@ -321,7 +326,8 @@ sha1_hmac_update(struct sha1_hmac_context *ctx, const byte *data, uint datalen)
sha1_update(&ctx->ictx, data, datalen);
}
byte *sha1_hmac_final(struct sha1_hmac_context *ctx)
byte *
sha1_hmac_final(struct sha1_hmac_context *ctx)
{
/* Finish the inner digest */
byte *isha = sha1_final(&ctx->ictx);
......@@ -334,9 +340,9 @@ byte *sha1_hmac_final(struct sha1_hmac_context *ctx)
void
sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen)
{
struct sha1_hmac_context hd;
sha1_hmac_init(&hd, key, keylen);
sha1_hmac_update(&hd, data, datalen);
byte *osha = sha1_hmac_final(&hd);
memcpy(outbuf, osha, SHA1_SIZE);
struct sha1_hmac_context ctx;
sha1_hmac_init(&ctx, key, keylen);
sha1_hmac_update(&ctx, data, datalen);
memcpy(outbuf, sha1_hmac_final(&ctx), SHA1_SIZE);
}
......@@ -17,70 +17,70 @@
#include "nest/bird.h"
#define SHA1_SIZE 20 /* Size of the SHA1 hash in its binary representation */
#define SHA1_HEX_SIZE 41 /* Buffer length for a string containing SHA1 in hexadecimal format. */
#define SHA1_BLOCK_SIZE 64 /* SHA1 splits input to blocks of this size. */
/*
* Internal SHA1 state.
* You should use it just as an opaque handle only.
*/
struct sha1_context {
u32 h0,h1,h2,h3,h4;
u32 nblocks;
byte buf[64];
int count;
} ;
u32 h0, h1, h2, h3, h4;
byte buf[SHA1_BLOCK_SIZE];
uint nblocks;
uint count;
};
void sha1_init(struct sha1_context *hd); /* Initialize new algorithm run in the @hd context. **/
void sha1_init(struct sha1_context *ctx); /* Initialize new algorithm run in the @ctx context. **/
/*
* Push another @inlen bytes of data pointed to by @inbuf onto the
* SHA1 hash currently in @hd. You can call this any times you want on
* the same hash (and you do not need to reinitialize it by
* @sha1_init()). It has the same effect as concatenating all the data
* together and passing them at once.
* Push another @len bytes of data pointed to by @buf onto the SHA1 hash
* currently in @ctx. You can call this any times you want on the same hash (and
* you do not need to reinitialize it by @sha1_init()). It has the same effect
* as concatenating all the data together and passing them at once.
*/
void sha1_update(struct sha1_context *hd, const byte *inbuf, uint inlen);
void sha1_update(struct sha1_context *ctx, const byte *buf, uint len);
/*
* No more @sha1_update() calls will be done. This terminates the hash
* and returns a pointer to it.
*
* Note that the pointer points into data in the @hd context. If it ceases
* to exist, the pointer becomes invalid.
* No more @sha1_update() calls will be done. This terminates the hash and
* returns a pointer to it.
*
* To convert the hash to its usual hexadecimal representation, see
* <<string:mem_to_hex()>>.
* Note that the pointer points into data in the @ctx context. If it ceases to
* exist, the pointer becomes invalid.
*/
byte *sha1_final(struct sha1_context *hd);
byte *sha1_final(struct sha1_context *ctx);
/*
* A convenience one-shot function for SHA1 hash.
* It is equivalent to this snippet of code:
* A convenience one-shot function for SHA1 hash. It is equivalent to this
* snippet of code:
*
* sha1_context hd;
* sha1_init(&hd);
* sha1_update(&hd, buffer, length);
* memcpy(outbuf, sha1_final(&hd), SHA1_SIZE);
* sha1_context ctx;
* sha1_init(&ctx);
* sha1_update(&ctx, buffer, length);
* memcpy(outbuf, sha1_final(&ctx), SHA1_SIZE);
*/
void sha1_hash_buffer(byte *outbuf, const byte *buffer, uint length);
/*
* SHA1 HMAC message authentication. If you provide @key and @data,
* the result will be stored in @outbuf.
* SHA1 HMAC message authentication. If you provide @key and @data, the result
* will be stored in @outbuf.
*/
void sha1_hmac(byte *outbuf, const byte *key, uint keylen, const byte *data, uint datalen);
/*
* The HMAC also exists in a stream version in a way analogous to the
* plain SHA1. Pass this as a context.
* The HMAC also exists in a stream version in a way analogous to the plain
* SHA1. Pass this as a context.
*/
struct sha1_hmac_context {
struct sha1_context ictx;
struct sha1_context octx;
};
void sha1_hmac_init(struct sha1_hmac_context *hd, const byte *key, uint keylen); /* Initialize HMAC with context @hd and the given key. See sha1_init(). */
void sha1_hmac_update(struct sha1_hmac_context *hd, const byte *data, uint datalen); /* Hash another @datalen bytes of data. See sha1_update(). */
byte *sha1_hmac_final(struct sha1_hmac_context *hd); /* Terminate the HMAC and return a pointer to the allocated hash. See sha1_final(). */
void sha1_hmac_init(struct sha1_hmac_context *ctx, const byte *key, uint keylen); /* Initialize HMAC with context @ctx and the given key. See sha1_init(). */
void sha1_hmac_update(struct sha1_hmac_context *ctx, const byte *data, uint datalen); /* Hash another @datalen bytes of data. See sha1_update(). */
byte *sha1_hmac_final(struct sha1_hmac_context *ctx); /* Terminate the HMAC and return a pointer to the allocated hash. See sha1_final(). */
#define SHA1_SIZE 20 /* Size of the SHA1 hash in its binary representation **/
#define SHA1_HEX_SIZE 41 /* Buffer length for a string containing SHA1 in hexadecimal format. **/
#define SHA1_BLOCK_SIZE 64 /* SHA1 splits input to blocks of this size. **/
#endif /* _BIRD_SHA1_H_ */
This diff is collapsed.
......@@ -15,6 +15,7 @@
#include "nest/bird.h"
#define SHA224_SIZE 28
#define SHA224_HEX_SIZE 57
#define SHA224_BLOCK_SIZE 64
......@@ -23,44 +24,44 @@
#define SHA256_HEX_SIZE 65
#define SHA256_BLOCK_SIZE 64
struct sha256_context {
u32 h0,h1,h2,h3,h4,h5,h6,h7;
byte buf[128]; /* 128 is for SHA384 and SHA512 support, otherwise for SHA224 and SHA256 is 64 enough */
u32 nblocks;
u32 nblocks_high;
int count;
u32 blocksize;
uint (*transform)(void *c, const byte *blks, size_t nblks);
u32 h0, h1, h2, h3, h4, h5, h6, h7;
byte buf[SHA256_BLOCK_SIZE];
uint nblocks;
uint count;
};
#define sha224_context sha256_context /* aliasing 'struct sha224_context' to 'struct sha256_context' */
#define sha224_context sha256_context
void sha256_init(struct sha256_context *ctx);
void sha224_init(struct sha224_context *ctx);
void sha256_update(struct sha256_context *ctx, const byte *in_buf, size_t in_len);
static inline void sha224_update(struct sha224_context *ctx, const byte *in_buf, size_t in_len)
{
sha256_update(ctx, in_buf, in_len);
}
void sha256_update(struct sha256_context *ctx, const byte *buf, size_t len);
static inline void sha224_update(struct sha224_context *ctx, const byte *buf, size_t len)
{ sha256_update(ctx, buf, len); }
byte *sha256_final(struct sha256_context *ctx);
static inline byte *sha224_final(struct sha224_context *ctx)
{ return sha256_final(ctx); }
byte* sha256_final(struct sha256_context *ctx);
static inline byte* sha224_final(struct sha224_context *ctx)
{
return sha256_final(ctx);
}
/*
* HMAC-SHA256, HMAC-SHA224
*/
struct sha256_hmac_context
{
struct sha256_context ictx;
struct sha256_context octx;
};
#define sha224_hmac_context sha256_hmac_context /* aliasing 'struct sha224_hmac_context' to 'struct sha256_hmac_context' */
#define sha224_hmac_context sha256_hmac_context
void sha256_hmac_init(struct sha256_hmac_context *ctx, const byte *key, size_t keylen);
void sha224_hmac_init(struct sha224_hmac_context *ctx, const byte *key, size_t keylen);
void sha224_hmac_init(struct sha224_hmac_context *ctx, const byte *key, size_t keylen);
void sha256_hmac_update(struct sha256_hmac_context *ctx, const byte *buf, size_t buflen);
void sha224_hmac_update(struct sha224_hmac_context *ctx, const byte *buf, size_t buflen);
......@@ -68,4 +69,5 @@ void sha224_hmac_update(struct sha224_hmac_context *ctx, const byte *buf, size_t
byte *sha256_hmac_final(struct sha256_hmac_context *ctx);
byte *sha224_hmac_final(struct sha224_hmac_context *ctx);
#endif /* _BIRD_SHA256_H_ */
This diff is collapsed.
......@@ -13,7 +13,8 @@
#ifndef _BIRD_SHA512_H_
#define _BIRD_SHA512_H_
#include "lib/sha256.h"
#include "nest/bird.h"
#define SHA384_SIZE 48
#define SHA384_HEX_SIZE 97
......@@ -23,43 +24,41 @@
#define SHA512_HEX_SIZE 129
#define SHA512_BLOCK_SIZE 128
struct sha512_state
{
struct sha512_context {
u64 h0, h1, h2, h3, h4, h5, h6, h7;
byte buf[SHA512_BLOCK_SIZE];
uint nblocks;
uint count;
};
struct sha512_context
{
struct sha256_context bctx;
struct sha512_state state;
};
#define sha384_context sha512_context /* aliasing 'struct sha384_context' to 'struct sha512_context' */
#define sha384_context sha512_context
void sha512_init(struct sha512_context *ctx);
void sha384_init(struct sha384_context *ctx);
void sha512_update(struct sha512_context *ctx, const byte *in_buf, size_t in_len);
static inline void sha384_update(struct sha384_context *ctx, const byte *in_buf, size_t in_len)
{
sha512_update(ctx, in_buf, in_len);
}
void sha512_update(struct sha512_context *ctx, const byte *buf, size_t len);
static inline void sha384_update(struct sha384_context *ctx, const byte *buf, size_t len)
{ sha512_update(ctx, buf, len); }
byte *sha512_final(struct sha512_context *ctx);
static inline byte *sha384_final(struct sha384_context *ctx)
{ return sha512_final(ctx); }
byte* sha512_final(struct sha512_context *ctx);
static inline byte* sha384_final(struct sha384_context *ctx)
{
return sha512_final(ctx);
}
/*
* HMAC-SHA512, HMAC-SHA384
*/
struct sha512_hmac_context
{
struct sha512_context ictx;
struct sha512_context octx;
} ;
#define sha384_hmac_context sha512_hmac_context /* aliasing 'struct sha384_hmac_context' to 'struct sha384_hmac_context' */
};
#define sha384_hmac_context sha512_hmac_context
void sha512_hmac_init(struct sha512_hmac_context *ctx, const byte *key, size_t keylen);
void sha384_hmac_init(struct sha384_hmac_context *ctx, const byte *key, size_t keylen);
......@@ -70,4 +69,5 @@ void sha384_hmac_update(struct sha384_hmac_context *ctx, const byte *buf, size_t
byte *sha512_hmac_final(struct sha512_hmac_context *ctx);
byte *sha384_hmac_final(struct sha384_hmac_context *ctx);
#endif /* _BIRD_SHA512_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment