nuttx-update/crypto/sha1.c
Alin Jerpelea a9e3614eaa crypto/sha1: migrate to SPDX identifier
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>
2024-12-17 08:37:13 +08:00

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));
}