mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 01:38:36 +08:00
6e92920464
Most tools used for compliance and SBOM generation use SPDX identifiers This change brings us a step closer to an easy SBOM generation. define NuttX local NuttX-PublicDomain identifier “Public Domain” is a concept distinct from copyright licensing; it generally means that the work no longer has any copyright protection or ownership, and therefore requires no license permission in order to use, copy, modify, distribute, perform, display, etc. In the United States – and many jurisdictions – copyright protections attach automatically to creative works upon creation if they satisfy certain minimum criteria. “Public Domain” would thus represent a significant change to the legal status of the work. The rules around “Public Domain” often vary or are unspecified jurisdiction to jurisdiction. Adding to the confusion, some jurisdictions may not even recognize the concept of “Public Domain” (or similar). As such, a license may nevertheless be required or implied in these cases. Even in the U.S., there is no clear, officially-sanctioned procedure for affirmatively placing copyright-eligible works into the “Public Domain” aside from natural statutory expiration of copyright. The bottom-line is, there are few if any objective, brightline rules for proactively placing copyright-eligible works into the Public Domain that we can broadly rely on. Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
299 lines
7.6 KiB
C
299 lines
7.6 KiB
C
/****************************************************************************
|
|
* crypto/sha1.c
|
|
*
|
|
* SPDX-License-Identifier: NuttX-PublicDomain
|
|
*
|
|
* By Steve Reid <steve@edmweb.com>
|
|
* 100% Public Domain
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <endian.h>
|
|
#include <string.h>
|
|
#include <sys/param.h>
|
|
|
|
#include <crypto/sha1.h>
|
|
|
|
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
|
|
|
|
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
|
|
|
#define SHA1HANDSOFF
|
|
|
|
#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 used in SHA1 */
|
|
#define R0(v,w,x,y,z,i) \
|
|
do \
|
|
{ \
|
|
z += ((w & (x ^ y)) ^ y) \
|
|
+ blk0(i) + 0x5a827999 + rol(v, 5); \
|
|
w = rol(w, 30); \
|
|
} \
|
|
while (0)
|
|
|
|
#define R1(v,w,x,y,z,i) \
|
|
do \
|
|
{ \
|
|
z += ((w & (x ^ y)) ^y) \
|
|
+ blk(i) + 0x5a827999 + rol(v, 5); \
|
|
w = rol(w, 30); \
|
|
} \
|
|
while (0)
|
|
|
|
#define R2(v,w,x,y,z,i) \
|
|
do \
|
|
{ \
|
|
z += (w ^ x ^ y) \
|
|
+ blk(i) + 0x6ed9eba1 + rol(v, 5); \
|
|
w = rol(w,30); \
|
|
} \
|
|
while (0)
|
|
|
|
#define R3(v,w,x,y,z,i) \
|
|
do \
|
|
{ \
|
|
z += (((w | x) & y) | (w & x)) \
|
|
+ blk(i)+ 0x8f1bbcdc + rol(v, 5); \
|
|
w = rol(w, 30); \
|
|
} \
|
|
while (0)
|
|
|
|
#define R4(v,w,x,y,z,i) \
|
|
do \
|
|
{ \
|
|
z += (w ^ x ^y) \
|
|
+ blk(i) + 0xca62c1d6 + rol(v, 5); \
|
|
w=rol(w, 30); \
|
|
} \
|
|
while (0)
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
|
|
|
void sha1transform(FAR uint32_t *state,
|
|
FAR const unsigned char *buffer)
|
|
{
|
|
uint32_t a;
|
|
uint32_t b;
|
|
uint32_t c;
|
|
uint32_t d;
|
|
uint32_t e;
|
|
|
|
typedef union
|
|
{
|
|
unsigned char c[64];
|
|
unsigned int l[16];
|
|
} CHAR64LONG16;
|
|
|
|
FAR CHAR64LONG16 *block;
|
|
|
|
#ifdef SHA1HANDSOFF
|
|
unsigned char workspace[SHA1_BLOCK_LENGTH];
|
|
|
|
block = (FAR CHAR64LONG16 *)workspace;
|
|
memcpy(block, buffer, SHA1_BLOCK_LENGTH);
|
|
#else
|
|
block = (FAR CHAR64LONG16 *)buffer;
|
|
#endif
|
|
|
|
/* 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(FAR 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(FAR SHA1_CTX *context,
|
|
FAR const void *dataptr,
|
|
unsigned int len)
|
|
{
|
|
FAR const uint8_t *data = dataptr;
|
|
unsigned int i;
|
|
unsigned int j;
|
|
|
|
j = (uint32_t)((context->count >> 3) & 63);
|
|
context->count += (len << 3);
|
|
if ((j + len) > 63)
|
|
{
|
|
memcpy(&context->buffer[j], data, (i = 64 - j));
|
|
sha1transform(context->state, context->buffer);
|
|
for (; i + 63 < len; i += 64)
|
|
{
|
|
sha1transform(context->state, &data[i]);
|
|
}
|
|
|
|
j = 0;
|
|
}
|
|
else
|
|
{
|
|
i = 0;
|
|
}
|
|
|
|
memcpy(&context->buffer[j], &data[i], len - i);
|
|
}
|
|
|
|
/* Add padding and return the message digest. */
|
|
|
|
void sha1final(FAR unsigned char *digest,
|
|
FAR SHA1_CTX *context)
|
|
{
|
|
unsigned int i;
|
|
unsigned char finalcount[8];
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
finalcount[i] = (unsigned char)((context->count >>
|
|
((7 - (i & 7)) * 8)) & 255); /* Endian independent */
|
|
}
|
|
|
|
sha1update(context, "\200", 1);
|
|
while ((context->count & 504) != 448)
|
|
{
|
|
sha1update(context, "\0", 1);
|
|
}
|
|
|
|
sha1update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
|
for (i = 0; i < SHA1_DIGEST_LENGTH; i++)
|
|
{
|
|
digest[i] = (unsigned char)((context->state[i >> 2] >>
|
|
((3 - (i & 3)) * 8)) & 255);
|
|
}
|
|
|
|
explicit_bzero(&finalcount, sizeof(finalcount));
|
|
explicit_bzero(context, sizeof(*context));
|
|
}
|