coreboot-kgpe-d16/payloads/libpayload/crypto/sha1.c
Gabe Black 1ee2c6dbdf libpayload: Change CONFIG_* to CONFIG_LP_* in the kconfig.
When libpayload header files are included in the payload itself, it's possible
that the payloads config settings will conflict with the ones in libpayload.
It's also possible for the libpayload config settings to conflict with the
payloads. To avoid that, the libpayload config settings have _LP_ (for
libpayload) added to them. The symbols themselves as defined in the Config.in files
are still the same, but the prefix added to them is now CONFIG_LP_ instead of just
CONFIG_.

Change-Id: Ib8a46d202e7880afdeac7924d69a949bfbcc5f97
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/65303
Reviewed-by: Stefan Reinauer <reinauer@google.com>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 23e866da20862cace0ed2a67d6fb74056bc9ea9a)
Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com>
Reviewed-on: http://review.coreboot.org/6427
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
2014-08-05 18:44:08 +02:00

214 lines
6.1 KiB
C

/*
* This file is part of the libpayload project.
*
* It has originally been taken from the OpenBSD project.
*/
/* $OpenBSD: sha1.c,v 1.20 2005/08/08 08:05:35 espie Exp $ */
/*
* SHA-1 in C
* By Steve Reid <steve@edmweb.com>
* 100% Public Domain
*
* Test Vectors (from FIPS PUB 180-1)
* "abc"
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
* A million repetitions of "a"
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#include <libpayload-config.h>
#include <libpayload.h>
typedef u8 u_int8_t;
typedef u32 u_int32_t;
typedef u64 u_int64_t;
typedef unsigned int u_int;
/* Moved from libpayload.h */
#ifdef CONFIG_LP_LITTLE_ENDIAN
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN
#endif
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/*
* blk0() and blk() perform the initial expand.
* I got the idea of expanding during the round function from SSLeay
*/
#if BYTE_ORDER == LITTLE_ENDIAN
# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
# define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/*
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
*/
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/*
* Hash a single 512-bit block. This is the core of the algorithm.
*/
void
SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
{
u_int32_t a, b, c, d, e;
u_int8_t workspace[SHA1_BLOCK_LENGTH];
typedef union {
u_int8_t c[64];
u_int32_t l[16];
} CHAR64LONG16;
CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/*
* SHA1Init - Initialize new context
*/
void
SHA1Init(SHA1_CTX *context)
{
/* SHA1 initialization constants */
context->count = 0;
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
}
/*
* Run your data through this.
*/
void
SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
{
size_t i, j;
j = (size_t)((context->count >> 3) & 63);
context->count += (len << 3);
if ((j + len) > 63) {
(void)memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64)
SHA1Transform(context->state, (u_int8_t *)&data[i]);
j = 0;
} else {
i = 0;
}
(void)memcpy(&context->buffer[j], &data[i], len - i);
}
/*
* Add padding and return the message digest.
*/
void
SHA1Pad(SHA1_CTX *context)
{
u_int8_t finalcount[8];
u_int i;
for (i = 0; i < 8; i++) {
finalcount[i] = (u_int8_t)((context->count >>
((7 - (i & 7)) * 8)) & 255); /* Endian independent */
}
SHA1Update(context, (u_int8_t *)"\200", 1);
while ((context->count & 504) != 448)
SHA1Update(context, (u_int8_t *)"\0", 1);
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
}
void
SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
{
u_int i;
SHA1Pad(context);
if (digest) {
for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
digest[i] = (u_int8_t)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
memset(context, 0, sizeof(*context));
}
}
/**
* Compute the SHA-1 hash of the given data as specified by the 'data' and
* 'len' arguments, and place the result -- 160 bits (20 bytes) -- into the
* specified output buffer 'buf'.
*
* @param data Pointer to the input data that shall be hashed.
* @param len Length of the input data (in bytes).
* @param buf Buffer which will hold the resulting hash (must be at
* least 20 bytes in size).
* @return Pointer to the output buffer where the hash is stored.
*/
u8 *sha1(const u8 *data, size_t len, u8 *buf)
{
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, data, len);
SHA1Final(buf, &ctx);
return buf;
}