nuttx-update/crypto/cast.c
Alin Jerpelea 4c48884ddf crypto/cast: 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-16 14:18:35 +08:00

357 lines
10 KiB
C

/****************************************************************************
* crypto/cast.c
*
* SPDX-License-Identifier: NuttX-PublicDomain
*
* CAST-128 in C
* Written by Steve Reid <sreid@sea-to-sky.net>
* 100% Public Domain - no warranty
* Released 1997.10.11
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <sys/types.h>
#include <crypto/cast.h>
#include "castsb.h"
/* Macros to access 8-bit bytes out of a 32-bit word */
#define UINT8_TA(x) ( (uint8_t) (x>>24) )
#define UINT8_TB(x) ( (uint8_t) ((x>>16)&255) )
#define UINT8_TC(x) ( (uint8_t) ((x>>8)&255) )
#define UINT8_TD(x) ( (uint8_t) ((x)&255) )
/* Circular left shift */
#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
/* CAST-128 uses three different round functions */
#define F1(l, r, i) \
t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
l ^= ((cast_sbox1[UINT8_TA(t)] ^ cast_sbox2[UINT8_TB(t)]) - \
cast_sbox3[UINT8_TC(t)]) + cast_sbox4[UINT8_TD(t)];
#define F2(l, r, i) \
t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
l ^= ((cast_sbox1[UINT8_TA(t)] - cast_sbox2[UINT8_TB(t)]) + \
cast_sbox3[UINT8_TC(t)]) ^ cast_sbox4[UINT8_TD(t)];
#define F3(l, r, i) \
t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
l ^= ((cast_sbox1[UINT8_TA(t)] + cast_sbox2[UINT8_TB(t)]) ^ \
cast_sbox3[UINT8_TC(t)]) - cast_sbox4[UINT8_TD(t)];
/****************************************************************************
* Public Functions
****************************************************************************/
/* Encryption Function */
void cast_encrypt(FAR cast_key *key,
FAR uint8_t *inblock,
FAR uint8_t *outblock)
{
uint32_t t;
uint32_t l;
uint32_t r;
/* Get inblock into l,r */
l = ((uint32_t)inblock[0] << 24) |
((uint32_t)inblock[1] << 16) |
((uint32_t)inblock[2] << 8) |
(uint32_t)inblock[3];
r = ((uint32_t)inblock[4] << 24) |
((uint32_t)inblock[5] << 16) |
((uint32_t)inblock[6] << 8) |
(uint32_t)inblock[7];
/* Do the work */
F1(l, r, 0);
F2(r, l, 1);
F3(l, r, 2);
F1(r, l, 3);
F2(l, r, 4);
F3(r, l, 5);
F1(l, r, 6);
F2(r, l, 7);
F3(l, r, 8);
F1(r, l, 9);
F2(l, r, 10);
F3(r, l, 11);
/* Only do full 16 rounds if key length > 80 bits */
if (key->rounds > 12)
{
F1(l, r, 12);
F2(r, l, 13);
F3(l, r, 14);
F1(r, l, 15);
}
/* Put l,r into outblock */
outblock[0] = UINT8_TA(r);
outblock[1] = UINT8_TB(r);
outblock[2] = UINT8_TC(r);
outblock[3] = UINT8_TD(r);
outblock[4] = UINT8_TA(l);
outblock[5] = UINT8_TB(l);
outblock[6] = UINT8_TC(l);
outblock[7] = UINT8_TD(l);
/* Wipe clean */
t = l = r = 0;
}
/* Decryption Function */
void cast_decrypt(FAR cast_key *key,
FAR uint8_t *inblock,
FAR uint8_t *outblock)
{
uint32_t t;
uint32_t l;
uint32_t r;
/* Get inblock into l,r */
r = ((uint32_t)inblock[0] << 24) |
((uint32_t)inblock[1] << 16) |
((uint32_t)inblock[2] << 8) |
(uint32_t)inblock[3];
l = ((uint32_t)inblock[4] << 24) |
((uint32_t)inblock[5] << 16) |
((uint32_t)inblock[6] << 8) |
(uint32_t)inblock[7];
/* Do the work */
/* Only do full 16 rounds if key length > 80 bits */
if (key->rounds > 12)
{
F1(r, l, 15);
F3(l, r, 14);
F2(r, l, 13);
F1(l, r, 12);
}
F3(r, l, 11);
F2(l, r, 10);
F1(r, l, 9);
F3(l, r, 8);
F2(r, l, 7);
F1(l, r, 6);
F3(r, l, 5);
F2(l, r, 4);
F1(r, l, 3);
F3(l, r, 2);
F2(r, l, 1);
F1(l, r, 0);
/* Put l,r into outblock */
outblock[0] = UINT8_TA(l);
outblock[1] = UINT8_TB(l);
outblock[2] = UINT8_TC(l);
outblock[3] = UINT8_TD(l);
outblock[4] = UINT8_TA(r);
outblock[5] = UINT8_TB(r);
outblock[6] = UINT8_TC(r);
outblock[7] = UINT8_TD(r);
/* Wipe clean */
t = l = r = 0;
}
/* Key Schedule */
void cast_setkey(FAR cast_key *key, FAR uint8_t *rawkey, int keybytes)
{
uint32_t t[4];
uint32_t z[4];
uint32_t x[4];
int i;
/* Set number of rounds to 12 or 16, depending on key length */
key->rounds = (keybytes <= 10 ? 12 : 16);
/* Copy key to workspace x */
for (i = 0; i < 4; i++)
{
x[i] = 0;
if ((i * 4 + 0) < keybytes)
{
x[i] = (uint32_t)rawkey[i * 4 + 0] << 24;
}
if ((i * 4 + 1) < keybytes)
{
x[i] |= (uint32_t)rawkey[i * 4 + 1] << 16;
}
if ((i * 4 + 2) < keybytes)
{
x[i] |= (uint32_t)rawkey[i * 4 + 2] << 8;
}
if ((i * 4 + 3) < keybytes)
{
x[i] |= (uint32_t)rawkey[i * 4 + 3];
}
}
/* Generate 32 subkeys, four at a time */
for (i = 0; i < 32; i += 4)
{
switch (i & 4)
{
case 0:
t[0] = z[0] = x[0] ^ cast_sbox5[UINT8_TB(x[3])] ^
cast_sbox6[UINT8_TD(x[3])] ^
cast_sbox7[UINT8_TA(x[3])] ^
cast_sbox8[UINT8_TC(x[3])] ^
cast_sbox7[UINT8_TA(x[2])];
t[1] = z[1] = x[2] ^ cast_sbox5[UINT8_TA(z[0])] ^
cast_sbox6[UINT8_TC(z[0])] ^
cast_sbox7[UINT8_TB(z[0])] ^
cast_sbox8[UINT8_TD(z[0])] ^
cast_sbox8[UINT8_TC(x[2])];
t[2] = z[2] = x[3] ^ cast_sbox5[UINT8_TD(z[1])] ^
cast_sbox6[UINT8_TC(z[1])] ^
cast_sbox7[UINT8_TB(z[1])] ^
cast_sbox8[UINT8_TA(z[1])] ^
cast_sbox5[UINT8_TB(x[2])];
t[3] = z[3] = x[1] ^ cast_sbox5[UINT8_TC(z[2])] ^
cast_sbox6[UINT8_TB(z[2])] ^
cast_sbox7[UINT8_TD(z[2])] ^
cast_sbox8[UINT8_TA(z[2])] ^
cast_sbox6[UINT8_TD(x[2])];
break;
case 4:
t[0] = x[0] = z[2] ^ cast_sbox5[UINT8_TB(z[1])] ^
cast_sbox6[UINT8_TD(z[1])] ^
cast_sbox7[UINT8_TA(z[1])] ^
cast_sbox8[UINT8_TC(z[1])] ^
cast_sbox7[UINT8_TA(z[0])];
t[1] = x[1] = z[0] ^ cast_sbox5[UINT8_TA(x[0])] ^
cast_sbox6[UINT8_TC(x[0])] ^
cast_sbox7[UINT8_TB(x[0])] ^
cast_sbox8[UINT8_TD(x[0])] ^
cast_sbox8[UINT8_TC(z[0])];
t[2] = x[2] = z[1] ^ cast_sbox5[UINT8_TD(x[1])] ^
cast_sbox6[UINT8_TC(x[1])] ^
cast_sbox7[UINT8_TB(x[1])] ^
cast_sbox8[UINT8_TA(x[1])] ^
cast_sbox5[UINT8_TB(z[0])];
t[3] = x[3] = z[3] ^ cast_sbox5[UINT8_TC(x[2])] ^
cast_sbox6[UINT8_TB(x[2])] ^
cast_sbox7[UINT8_TD(x[2])] ^
cast_sbox8[UINT8_TA(x[2])] ^
cast_sbox6[UINT8_TD(z[0])];
break;
}
switch (i & 12)
{
case 0:
case 12:
key->xkey[i + 0] = cast_sbox5[UINT8_TA(t[2])] ^
cast_sbox6[UINT8_TB(t[2])] ^
cast_sbox7[UINT8_TD(t[1])] ^
cast_sbox8[UINT8_TC(t[1])];
key->xkey[i + 1] = cast_sbox5[UINT8_TC(t[2])] ^
cast_sbox6[UINT8_TD(t[2])] ^
cast_sbox7[UINT8_TB(t[1])] ^
cast_sbox8[UINT8_TA(t[1])];
key->xkey[i + 2] = cast_sbox5[UINT8_TA(t[3])] ^
cast_sbox6[UINT8_TB(t[3])] ^
cast_sbox7[UINT8_TD(t[0])] ^
cast_sbox8[UINT8_TC(t[0])];
key->xkey[i + 3] = cast_sbox5[UINT8_TC(t[3])] ^
cast_sbox6[UINT8_TD(t[3])] ^
cast_sbox7[UINT8_TB(t[0])] ^
cast_sbox8[UINT8_TA(t[0])];
break;
case 4:
case 8:
key->xkey[i + 0] = cast_sbox5[UINT8_TD(t[0])] ^
cast_sbox6[UINT8_TC(t[0])] ^
cast_sbox7[UINT8_TA(t[3])] ^
cast_sbox8[UINT8_TB(t[3])];
key->xkey[i + 1] = cast_sbox5[UINT8_TB(t[0])] ^
cast_sbox6[UINT8_TA(t[0])] ^
cast_sbox7[UINT8_TC(t[3])] ^
cast_sbox8[UINT8_TD(t[3])];
key->xkey[i + 2] = cast_sbox5[UINT8_TD(t[1])] ^
cast_sbox6[UINT8_TC(t[1])] ^
cast_sbox7[UINT8_TA(t[2])] ^
cast_sbox8[UINT8_TB(t[2])];
key->xkey[i + 3] = cast_sbox5[UINT8_TB(t[1])] ^
cast_sbox6[UINT8_TA(t[1])] ^
cast_sbox7[UINT8_TC(t[2])] ^
cast_sbox8[UINT8_TD(t[2])];
break;
}
switch (i & 12)
{
case 0:
key->xkey[i + 0] ^= cast_sbox5[UINT8_TC(z[0])];
key->xkey[i + 1] ^= cast_sbox6[UINT8_TC(z[1])];
key->xkey[i + 2] ^= cast_sbox7[UINT8_TB(z[2])];
key->xkey[i + 3] ^= cast_sbox8[UINT8_TA(z[3])];
break;
case 4:
key->xkey[i + 0] ^= cast_sbox5[UINT8_TA(x[2])];
key->xkey[i + 1] ^= cast_sbox6[UINT8_TB(x[3])];
key->xkey[i + 2] ^= cast_sbox7[UINT8_TD(x[0])];
key->xkey[i + 3] ^= cast_sbox8[UINT8_TD(x[1])];
break;
case 8:
key->xkey[i + 0] ^= cast_sbox5[UINT8_TB(z[2])];
key->xkey[i + 1] ^= cast_sbox6[UINT8_TA(z[3])];
key->xkey[i + 2] ^= cast_sbox7[UINT8_TC(z[0])];
key->xkey[i + 3] ^= cast_sbox8[UINT8_TC(z[1])];
break;
case 12:
key->xkey[i + 0] ^= cast_sbox5[UINT8_TD(x[0])];
key->xkey[i + 1] ^= cast_sbox6[UINT8_TD(x[1])];
key->xkey[i + 2] ^= cast_sbox7[UINT8_TA(x[2])];
key->xkey[i + 3] ^= cast_sbox8[UINT8_TB(x[3])];
break;
}
if (i >= 16)
{
key->xkey[i + 0] &= 31;
key->xkey[i + 1] &= 31;
key->xkey[i + 2] &= 31;
key->xkey[i + 3] &= 31;
}
}
/* Wipe clean */
explicit_bzero(t, sizeof(t));
explicit_bzero(x, sizeof(x));
explicit_bzero(z, sizeof(z));
}
/* Made in Canada */