#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#ifdef WOLFSSL_RISCV_ASM
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
#if FIPS_VERSION3_LT(6,0,0) && defined(HAVE_FIPS)
#undef HAVE_FIPS
#else
#if defined(HAVE_FIPS) && FIPS_VERSION3_GE(6,0,0)
#define FIPS_NO_WRAPPERS
#endif
#endif
#include <wolfssl/wolfcrypt/sha512.h>
#if FIPS_VERSION3_GE(6,0,0)
const unsigned int wolfCrypt_FIPS_sha512_ro_sanity[2] =
{ 0x1a2b3c4d, 0x00000014 };
int wolfCrypt_FIPS_SHA512_sanity(void)
{
return 0;
}
#endif
#include <wolfssl/wolfcrypt/port/riscv/riscv-64-asm.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
static const word64 K512[80] = {
W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
};
static int InitSha512(wc_Sha512* sha512, void* heap, int devId)
{
int ret = 0;
if (sha512 == NULL) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
sha512->heap = heap;
#ifdef WOLF_CRYPTO_CB
sha512->devId = devId;
#endif
(void)devId;
#ifdef WOLFSSL_SMALL_STACK_CACHE
sha512->W = NULL;
#endif
#ifdef WOLFSSL_HASH_FLAGS
sha512->flags = 0;
#endif
}
return ret;
}
static void InitSha512_State(wc_Sha512* sha512)
{
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
sha512->digest[4] = W64LIT(0x510e527fade682d1);
sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
#else
sha512->digest[0] = W64LIT(0x9b05688c2b3e6c1f);
sha512->digest[1] = W64LIT(0x510e527fade682d1);
sha512->digest[2] = W64LIT(0xbb67ae8584caa73b);
sha512->digest[3] = W64LIT(0x6a09e667f3bcc908);
sha512->digest[4] = W64LIT(0x5be0cd19137e2179);
sha512->digest[5] = W64LIT(0x1f83d9abfb41bd6b);
sha512->digest[6] = W64LIT(0xa54ff53a5f1d36f1);
sha512->digest[7] = W64LIT(0x3c6ef372fe94f82b);
#endif
sha512->buffLen = 0;
sha512->loLen = 0;
sha512->hiLen = 0;
}
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if !defined(WOLFSSL_NOSHA512_224)
static void InitSha512_224_State(wc_Sha512* sha512)
{
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
sha512->digest[0] = W64LIT(0x8c3d37c819544da2);
sha512->digest[1] = W64LIT(0x73e1996689dcd4d6);
sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82);
sha512->digest[3] = W64LIT(0x679dd514582f9fcf);
sha512->digest[4] = W64LIT(0x0f6d2b697bd44da8);
sha512->digest[5] = W64LIT(0x77e36f7304c48942);
sha512->digest[6] = W64LIT(0x3f9d85a86a1d36c8);
sha512->digest[7] = W64LIT(0x1112e6ad91d692a1);
#else
sha512->digest[0] = W64LIT(0x77e36f7304c48942);
sha512->digest[1] = W64LIT(0x0f6d2b697bd44da8);
sha512->digest[2] = W64LIT(0x73e1996689dcd4d6);
sha512->digest[3] = W64LIT(0x8c3d37c819544da2);
sha512->digest[4] = W64LIT(0x1112e6ad91d692a1);
sha512->digest[5] = W64LIT(0x3f9d85a86a1d36c8);
sha512->digest[6] = W64LIT(0x679dd514582f9fcf);
sha512->digest[7] = W64LIT(0x1dfab7ae32ff9c82);
#endif
sha512->buffLen = 0;
sha512->loLen = 0;
sha512->hiLen = 0;
}
#endif
#endif
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if !defined(WOLFSSL_NOSHA512_256)
static void InitSha512_256_State(wc_Sha512* sha512)
{
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
sha512->digest[0] = W64LIT(0x22312194fc2bf72c);
sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2);
sha512->digest[2] = W64LIT(0x2393b86b6f53b151);
sha512->digest[3] = W64LIT(0x963877195940eabd);
sha512->digest[4] = W64LIT(0x96283ee2a88effe3);
sha512->digest[5] = W64LIT(0xbe5e1e2553863992);
sha512->digest[6] = W64LIT(0x2b0199fc2c85b8aa);
sha512->digest[7] = W64LIT(0x0eb72ddc81c52ca2);
#else
sha512->digest[0] = W64LIT(0xbe5e1e2553863992);
sha512->digest[1] = W64LIT(0x96283ee2a88effe3);
sha512->digest[2] = W64LIT(0x9f555fa3c84c64c2);
sha512->digest[3] = W64LIT(0x22312194fc2bf72c);
sha512->digest[4] = W64LIT(0x0eb72ddc81c52ca2);
sha512->digest[5] = W64LIT(0x2b0199fc2c85b8aa);
sha512->digest[6] = W64LIT(0x963877195940eabd);
sha512->digest[7] = W64LIT(0x2393b86b6f53b151);
#endif
sha512->buffLen = 0;
sha512->loLen = 0;
sha512->hiLen = 0;
}
#endif
#endif
static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
{
word32 tmp = sha512->loLen;
if ((sha512->loLen += len) < tmp)
sha512->hiLen++;
}
#ifndef WOLFSSL_RISCV_BASE_BIT_MANIPULATION
#define LOAD_DWORD_REV(r, o, p, t0, t1, t2, t3) \
"lbu " #t0 ", " #o "+4(" #p ")\n\t" \
"lbu " #t1 ", " #o "+5(" #p ")\n\t" \
"lbu " #t2 ", " #o "+6(" #p ")\n\t" \
"lbu " #r ", " #o "+7(" #p ")\n\t" \
"slli " #t0 ", " #t0 ", 24\n\t" \
"slli " #t1 ", " #t1 ", 16\n\t" \
"slli " #t2 ", " #t2 ", 8\n\t" \
"or " #r ", " #r ", " #t0 "\n\t" \
"or " #r ", " #r ", " #t1 "\n\t" \
"or " #r ", " #r ", " #t2 "\n\t" \
"lbu " #t0 ", " #o "+0(" #p ")\n\t" \
"lbu " #t1 ", " #o "+1(" #p ")\n\t" \
"lbu " #t2 ", " #o "+2(" #p ")\n\t" \
"lbu " #t3 ", " #o "+3(" #p ")\n\t" \
"slli " #t0 ", " #t0 ", 56\n\t" \
"slli " #t1 ", " #t1 ", 48\n\t" \
"slli " #t2 ", " #t2 ", 40\n\t" \
"slli " #t3 ", " #t3 ", 32\n\t" \
"or " #r ", " #r ", " #t0 "\n\t" \
"or " #r ", " #r ", " #t1 "\n\t" \
"or " #r ", " #r ", " #t2 "\n\t" \
"or " #r ", " #r ", " #t3 "\n\t"
#endif
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
#ifdef WOLFSSL_RISCV_SCALAR_CRYPTO_ASM
#define SHA512SUM0(rd, rs1) \
ASM_WORD((0b000100000100 << 20) | (0b001 << 12) | 0b0010011 | \
(rs1 << 15) | (rd << 7))
#define SHA512SUM1(rd, rs1) \
ASM_WORD((0b000100000101 << 20) | (0b001 << 12) | 0b0010011 | \
(rs1 << 15) | (rd << 7))
#define SHA512SIG0(rd, rs1) \
ASM_WORD((0b000100000110 << 20) | (0b001 << 12) | 0b0010011 | \
(rs1 << 15) | (rd << 7))
#define SHA512SIG1(rd, rs1) \
ASM_WORD((0b000100000111 << 20) | (0b001 << 12) | 0b0010011 | \
(rs1 << 15) | (rd << 7))
#define RND(a, b, c, d, e, f, g, h, w, k) \
\
"mv a4, " #e "\n\t" \
"mv a5, " #a "\n\t" \
\
SHA512SUM1(REG_A4, REG_A4) \
\
SHA512SUM0(REG_A5, REG_A5) \
\
\
\
"xor t4, " #a ", " #b "\n\t" \
\
"xor t6, " #f ", " #g "\n\t" \
\
"xor t5, " #b ", " #c "\n\t" \
\
"and t6, t6, " #e "\n\t" \
\
"and t5, t5, t4\n\t" \
\
"xor t6, t6, " #g "\n\t" \
\
"xor t5, t5, " #b "\n\t" \
\
"add t4, a4, t6\n\t" \
\
"add t6, " #k ", " #w "\n\t" \
\
"add t4, t4, t6\n\t" \
\
"add " #h ", " #h ", t4\n\t" \
\
"add t5, a5, t5\n\t" \
\
"add " #d ", " #d ", " #h "\n\t" \
\
"add " #h ", " #h ", t5\n\t"
#define W_UPDATE(w0, w1, w9, w14, reg_w0, reg_w1, reg_w9, reg_w14) \
\
SHA512SIG0(REG_A4, reg_w1) \
\
SHA512SIG1(REG_A5, reg_w14) \
\
"add a5, a5, " #w9 "\n\t" \
\
"add " #w0 ", " #w0 ", a4\n\t" \
\
"add " #w0 ", a5, " #w0 "\n\t"
#else
#define SHA512SUM0(rd, rs1) \
"slli t5, " #rs1 ", 36\n\t" \
"srli t4, " #rs1 ", 28\n\t" \
"slli t6, " #rs1 ", 30\n\t" \
"or t4, t4, t5\n\t" \
"srli t5, " #rs1 ", 34\n\t" \
"xor t4, t4, t6\n\t" \
"slli t6, " #rs1 ", 25\n\t" \
"xor t4, t4, t5\n\t" \
"srli " #rd ", " #rs1 ", 39\n\t" \
"xor t4, t4, t6\n\t" \
"xor " #rd ", " #rd ", t4\n\t"
#define SHA512SUM1(rd, rs1) \
"slli t5, " #rs1 ", 50\n\t" \
"srli t4, " #rs1 ", 14\n\t" \
"slli t6, " #rs1 ", 46\n\t" \
"or t4, t4, t5\n\t" \
"srli t5, " #rs1 ", 18\n\t" \
"xor t4, t4, t6\n\t" \
"slli t6, " #rs1 ", 23\n\t" \
"xor t4, t4, t5\n\t" \
"srli " #rd ", " #rs1 ", 41\n\t" \
"xor t4, t4, t6\n\t" \
"xor " #rd ", " #rd ", t4\n\t"
#define SHA512SIG0(rd, rs1) \
"slli t5, " #rs1 ", 63\n\t" \
"srli t6, " #rs1 ", 1\n\t" \
"slli t4, " #rs1 ", 56\n\t" \
"or t6, t6, t5\n\t" \
"srli t5, " #rs1 ", 8\n\t" \
"xor t6, t6, t4\n\t" \
"srli " #rd ", " #rs1 ", 7\n\t" \
"xor t6, t6, t5\n\t" \
"xor " #rd ", " #rd ", t6\n\t"
#define SHA512SIG1(rd, rs1) \
"slli t5, " #rs1 ", 45\n\t" \
"srli t6, " #rs1 ", 19\n\t" \
"slli t4, " #rs1 ", 3\n\t" \
"or t6, t6, t5\n\t" \
"srli t5, " #rs1 ", 61\n\t" \
"xor t6, t6, t4\n\t" \
"srli " #rd ", " #rs1 ", 6\n\t" \
"xor t6, t6, t5\n\t" \
"xor " #rd ", " #rd ", t6\n\t"
#define RND(a, b, c, d, e, f, g, h, w, k) \
\
SHA512SUM1(a4, e) \
\
SHA512SUM0(a5, a) \
\
\
\
"xor t4, " #a ", " #b "\n\t" \
\
"xor t6, " #f ", " #g "\n\t" \
\
"xor t5, " #b ", " #c "\n\t" \
\
"and t6, t6, " #e "\n\t" \
\
"and t5, t5, t4\n\t" \
\
"xor t6, t6, " #g "\n\t" \
\
"xor t5, t5, " #b "\n\t" \
\
"add t4, a4, t6\n\t" \
\
"add t6, " #k ", " #w "\n\t" \
\
"add t4, t4, t6\n\t" \
\
"add " #h ", " #h ", t4\n\t" \
\
"add t5, a5, t5\n\t" \
\
"add " #d ", " #d ", " #h "\n\t" \
\
"add " #h ", " #h ", t5\n\t"
#define W_UPDATE(w0, w1, w9, w14, reg_w0, reg_w1, reg_w9, reg_14) \
\
SHA512SIG0(a4, w1) \
\
SHA512SIG1(a5, w14) \
\
"add a5, a5, " #w9 "\n\t" \
\
"add " #w0 ", " #w0 ", a4\n\t" \
\
"add " #w0 ", a5, " #w0 "\n\t"
#endif
#define RND2_W(a, b, c, d, e, f, g, h, o, w2o, w9o, w10o) \
\
"ld a6, " #o "(%[k])\n\t" \
\
"ld a7, " #o "+8(%[k])\n\t" \
RND(a, b, c, d, e, f, g, h, s1, a6) \
\
"ld s2, " #o "+8(sp)\n\t" \
\
"ld s3, " #w9o "(sp)\n\t" \
W_UPDATE(s1, s2, s3, s4, REG_S1, REG_S2, REG_S3, REG_S4) \
RND(h, a, b, c, d, e, f, g, s2, a7) \
"mv s4, s1\n\t" \
\
"ld s1, " #w2o "(sp)\n\t" \
\
"ld s3, " #w10o "(sp)\n\t" \
W_UPDATE(s2, s1, s3, s5, REG_S2, REG_S1, REG_S3, REG_S5) \
"sd s4, " #o "(sp)\n\t" \
"mv s5, s2\n\t" \
"sd s2, " #o "+8(sp)\n\t"
#define RND16() \
RND2_W(t0, t1, t2, t3, s8, s9, s10, s11, 0, 16, 72, 80) \
RND2_W(s10, s11, t0, t1, t2, t3, s8, s9, 16, 32, 88, 96) \
RND2_W(s8, s9, s10, s11, t0, t1, t2, t3, 32, 48, 104, 112) \
RND2_W(t2, t3, s8, s9, s10, s11, t0, t1, 48, 64, 120, 0) \
RND2_W(t0, t1, t2, t3, s8, s9, s10, s11, 64, 80, 8, 16) \
RND2_W(s10, s11, t0, t1, t2, t3, s8, s9, 80, 96, 24, 32) \
RND2_W(s8, s9, s10, s11, t0, t1, t2, t3, 96, 112, 40, 48) \
RND2_W(t2, t3, s8, s9, s10, s11, t0, t1, 112, 0, 56, 64)
#define RND2(a, b, c, d, e, f, g, h, o) \
\
"ld a6, " #o "(%[k])\n\t" \
\
"ld s1, " #o "(sp)\n\t" \
RND(a, b, c, d, e, f, g, h, s1, a6) \
\
"ld a6, " #o "+8(%[k])\n\t" \
\
"ld s1, " #o "+8(sp)\n\t" \
RND(h, a, b, c, d, e, f, g, s1, a6)
#define RND16_LAST() \
RND2(t0, t1, t2, t3, s8, s9, s10, s11, 0) \
RND2(s10, s11, t0, t1, t2, t3, s8, s9, 16) \
RND2(s8, s9, s10, s11, t0, t1, t2, t3, 32) \
RND2(t2, t3, s8, s9, s10, s11, t0, t1, 48) \
RND2(t0, t1, t2, t3, s8, s9, s10, s11, 64) \
RND2(s10, s11, t0, t1, t2, t3, s8, s9, 80) \
RND2(s8, s9, s10, s11, t0, t1, t2, t3, 96) \
RND2(t2, t3, s8, s9, s10, s11, t0, t1, 112)
static WC_INLINE void Sha512Transform(wc_Sha512* sha512, const byte* data,
word32 blocks)
{
word64* k = (word64*)K512;
__asm__ __volatile__ (
"addi sp, sp, -128\n\t"
"ld t0, 0(%[digest])\n\t"
"ld t1, 8(%[digest])\n\t"
"ld t2, 16(%[digest])\n\t"
"ld t3, 24(%[digest])\n\t"
"ld s8, 32(%[digest])\n\t"
"ld s9, 40(%[digest])\n\t"
"ld s10, 48(%[digest])\n\t"
"ld s11, 56(%[digest])\n\t"
"slli %[blocks], %[blocks], 2\n\t"
"\n1:\n\t"
#ifndef WOLFSSL_RISCV_BASE_BIT_MANIPULATION
LOAD_DWORD_REV(t4, 0, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s1, 8, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s2, 16, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s3, 24, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s4, 32, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s5, 40, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s6, 48, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s7, 56, %[data], a4, a5, a6, a7)
#else
"ld t4, 0(%[data])\n\t"
"ld s1, 8(%[data])\n\t"
"ld s2, 16(%[data])\n\t"
"ld s3, 24(%[data])\n\t"
"ld s4, 32(%[data])\n\t"
"ld s5, 40(%[data])\n\t"
"ld s6, 48(%[data])\n\t"
"ld s7, 56(%[data])\n\t"
REV8(REG_T4, REG_T4)
REV8(REG_S1, REG_S1)
REV8(REG_S2, REG_S2)
REV8(REG_S3, REG_S3)
REV8(REG_S4, REG_S4)
REV8(REG_S5, REG_S5)
REV8(REG_S6, REG_S6)
REV8(REG_S7, REG_S7)
#endif
"sd t4, 0(sp)\n\t"
"sd s1, 8(sp)\n\t"
"sd s2, 16(sp)\n\t"
"sd s3, 24(sp)\n\t"
"sd s4, 32(sp)\n\t"
"sd s5, 40(sp)\n\t"
"sd s6, 48(sp)\n\t"
"sd s7, 56(sp)\n\t"
#ifndef WOLFSSL_RISCV_BASE_BIT_MANIPULATION
LOAD_DWORD_REV(t4, 64, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s1, 72, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s2, 80, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s3, 88, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s4, 96, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s5, 104, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s6, 112, %[data], a4, a5, a6, a7)
LOAD_DWORD_REV(s7, 120, %[data], a4, a5, a6, a7)
#else
"ld t4, 64(%[data])\n\t"
"ld s1, 72(%[data])\n\t"
"ld s2, 80(%[data])\n\t"
"ld s3, 88(%[data])\n\t"
"ld s4, 96(%[data])\n\t"
"ld s5, 104(%[data])\n\t"
"ld s6, 112(%[data])\n\t"
"ld s7, 120(%[data])\n\t"
REV8(REG_T4, REG_T4)
REV8(REG_S1, REG_S1)
REV8(REG_S2, REG_S2)
REV8(REG_S3, REG_S3)
REV8(REG_S4, REG_S4)
REV8(REG_S5, REG_S5)
REV8(REG_S6, REG_S6)
REV8(REG_S7, REG_S7)
#endif
"sd t4, 64(sp)\n\t"
"sd s1, 72(sp)\n\t"
"sd s2, 80(sp)\n\t"
"sd s3, 88(sp)\n\t"
"sd s4, 96(sp)\n\t"
"sd s5, 104(sp)\n\t"
"sd s6, 112(sp)\n\t"
"sd s7, 120(sp)\n\t"
"\n2:\n\t"
"ld s1, 0(sp)\n\t"
"ld s4, 112(sp)\n\t"
"ld s5, 120(sp)\n\t"
"addi %[blocks], %[blocks], -1\n\t"
RND16()
"andi a4, %[blocks], 3\n\t"
"add %[k], %[k], 128\n\t"
"bnez a4, 2b \n\t"
RND16_LAST()
"addi %[k], %[k], -512\n\t"
"# Add working vars back into digest state.\n\t"
"ld t4, 0(%[digest])\n\t"
"ld s1, 8(%[digest])\n\t"
"ld s2, 16(%[digest])\n\t"
"ld s3, 24(%[digest])\n\t"
"ld s4, 32(%[digest])\n\t"
"ld s5, 40(%[digest])\n\t"
"ld s6, 48(%[digest])\n\t"
"ld s7, 56(%[digest])\n\t"
"add t0, t0, t4\n\t"
"add t1, t1, s1\n\t"
"add t2, t2, s2\n\t"
"add t3, t3, s3\n\t"
"add s8, s8, s4\n\t"
"add s9, s9, s5\n\t"
"add s10, s10, s6\n\t"
"add s11, s11, s7\n\t"
"sd t0, 0(%[digest])\n\t"
"sd t1, 8(%[digest])\n\t"
"sd t2, 16(%[digest])\n\t"
"sd t3, 24(%[digest])\n\t"
"sd s8, 32(%[digest])\n\t"
"sd s9, 40(%[digest])\n\t"
"sd s10, 48(%[digest])\n\t"
"sd s11, 56(%[digest])\n\t"
"add %[data], %[data], 128\n\t"
"bnez %[blocks], 1b \n\t"
"addi sp, sp, 128\n\t"
: [blocks] "+r" (blocks), [data] "+r" (data), [k] "+r" (k)
: [digest] "r" (sha512->digest)
: "cc", "memory", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
"a4", "a5", "a6", "a7",
"s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10",
"s11"
);
}
#else
#define VSHA2CL_VV(vd, vs1, vs2) \
ASM_WORD((0b101111 << 26) | (0b1 << 25) | \
(0b010 << 12) | (0b1110111 << 0) | \
(vd << 7) | (vs1 << 15) | (vs2 << 20))
#define VSHA2CH_VV(vd, vs1, vs2) \
ASM_WORD((0b101110 << 26) | (0b1 << 25) | \
(0b010 << 12) | (0b1110111 << 0) | \
(vd << 7) | (vs1 << 15) | (vs2 << 20))
#define VSHA2MS_VV(vd, vs1, vs2) \
ASM_WORD((0b101101 << 26) | (0b1 << 25) | \
(0b010 << 12) | (0b1110111 << 0) | \
(vd << 7) | (vs1 << 15) | (vs2 << 20))
#define RND4(w0, w2, w4, w6, k) \
\
VADD_VV(REG_V14, w0, k) \
VMV_X_S(REG_T1, w2) \
VSHA2CL_VV(REG_V10, REG_V14, REG_V8) \
VMV_V_V(REG_V12, w4) \
VSHA2CH_VV(REG_V8, REG_V14, REG_V10) \
\
VMV_S_X(REG_V12, REG_T1) \
VSHA2MS_VV(w0, w6, REG_V12)
#define RND4_LAST(w, k) \
\
VADD_VV(REG_V14, w, k) \
VSHA2CL_VV(REG_V10, REG_V14, REG_V8) \
VSHA2CH_VV(REG_V8, REG_V14, REG_V10)
#define RND16(k) \
RND4(REG_V0, REG_V2, REG_V4, REG_V6, (k + 0)) \
RND4(REG_V2, REG_V4, REG_V6, REG_V0, (k + 2)) \
RND4(REG_V4, REG_V6, REG_V0, REG_V2, (k + 4)) \
RND4(REG_V6, REG_V0, REG_V2, REG_V4, (k + 6))
#define RND16_LAST(k) \
RND4_LAST(REG_V0, (k + 0)) \
RND4_LAST(REG_V2, (k + 2)) \
RND4_LAST(REG_V4, (k + 4)) \
RND4_LAST(REG_V6, (k + 6))
static void Sha512Transform(wc_Sha512* sha512, const byte* data,
word32 blocks)
{
word64* k = (word64*)K512;
__asm__ __volatile__ (
VSETIVLI(REG_ZERO, 4, 1, 1, 0b011, 0b001)
"mv t0, %[digest]\n\t"
VL4RE64_V(REG_V8, REG_T0)
"\n1:\n\t"
VMVR_V(REG_V28, REG_V8, 4)
"mv t0, %[data]\n\t"
VL8RE64_V(REG_V0, REG_T0)
VREV8(REG_V0, REG_V0)
VREV8(REG_V2, REG_V2)
VREV8(REG_V4, REG_V4)
VREV8(REG_V6, REG_V6)
"mv t0, %[k]\n\t"
VL8RE64_V(REG_V16, REG_T0)
RND16(REG_V16)
"addi t0, %[k], 128\n\t"
VL8RE64_V(REG_V16, REG_T0)
RND16(REG_V16)
"addi t0, %[k], 256\n\t"
VL8RE64_V(REG_V16, REG_T0)
RND16(REG_V16)
"addi t0, %[k], 384\n\t"
VL8RE64_V(REG_V16, REG_T0)
RND16(REG_V16)
"addi t0, %[k], 512\n\t"
VL8RE64_V(REG_V16, REG_T0)
RND16_LAST(REG_V16)
VADD_VV(REG_V8, REG_V8, REG_V28)
VADD_VV(REG_V10, REG_V10, REG_V30)
"addi %[blocks], %[blocks], -1\n\t"
"add %[data], %[data], 128\n\t"
"bnez %[blocks], 1b \n\t"
"mv t0, %[digest]\n\t"
VS4R_V(REG_V8, REG_T0)
: [blocks] "+r" (blocks), [data] "+r" (data), [k] "+r" (k)
: [digest] "r" (sha512->digest)
: "cc", "memory", "t0", "t1"
);
}
#endif
static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data,
word32 len)
{
word32 add;
word32 blocks;
if (len > 0) {
AddLength(sha512, len);
if (sha512->buffLen > 0) {
add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
XMEMCPY((byte*)(sha512->buffer) + sha512->buffLen, data, add);
sha512->buffLen += add;
data += add;
len -= add;
if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
Sha512Transform(sha512, (byte*)sha512->buffer, 1);
sha512->buffLen = 0;
}
}
blocks = len / WC_SHA512_BLOCK_SIZE;
if (blocks > 0) {
Sha512Transform(sha512, data, blocks);
data += blocks * WC_SHA512_BLOCK_SIZE;
len -= blocks * WC_SHA512_BLOCK_SIZE;
}
if (len > 0) {
XMEMCPY(sha512->buffer, data, len);
sha512->buffLen = len;
}
}
(void)add;
(void)blocks;
return 0;
}
static WC_INLINE void Sha512Final(wc_Sha512* sha512, byte* hash, int hashLen)
{
byte* local;
byte hashBuf[WC_SHA512_DIGEST_SIZE];
byte* hashRes = hash;
if (hashLen < WC_SHA512_DIGEST_SIZE) {
hashRes = hashBuf;
}
local = (byte*)sha512->buffer;
local[sha512->buffLen++] = 0x80;
if (sha512->buffLen > WC_SHA512_PAD_SIZE) {
XMEMSET(&local[sha512->buffLen], 0,
WC_SHA512_BLOCK_SIZE - sha512->buffLen);
Sha512Transform(sha512, (byte*)sha512->buffer, 1);
sha512->buffLen = 0;
}
XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
sha512->hiLen = (sha512->loLen >> (8*sizeof(sha512->loLen) - 3)) +
(sha512->hiLen << 3);
sha512->loLen = sha512->loLen << 3;
sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
__asm__ __volatile__ (
#if defined(WOLFSSL_RISCV_BASE_BIT_MANIPULATION)
"ld t0, 112(%[buff])\n\t"
"ld t1, 120(%[buff])\n\t"
REV8(REG_T0, REG_T0)
REV8(REG_T1, REG_T1)
#else
LOAD_DWORD_REV(t0, 112, %[buff], t2, t3, t4, t5)
LOAD_DWORD_REV(t1, 120, %[buff], t2, t3, t4, t5)
#endif
"sd t0, 112(%[buff])\n\t"
"sd t1, 120(%[buff])\n\t"
:
: [buff] "r" (sha512->buffer)
: "cc", "memory", "t0", "t1", "t2", "t3", "t4", "t5"
);
Sha512Transform(sha512, (byte*)sha512->buffer, 1);
__asm__ __volatile__ (
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
VSETIVLI(REG_ZERO, 4, 1, 1, 0b011, 0b001)
"mv t0, %[digest]\n\t"
VL4RE64_V(REG_V4, REG_T0)
VREV8(REG_V4, REG_V4)
VREV8(REG_V6, REG_V6)
VSETIVLI(REG_ZERO, 2, 1, 1, 0b011, 0b000)
VSLIDEDOWN_VI(REG_V0, REG_V5, 1)
VSLIDEDOWN_VI(REG_V1, REG_V7, 1)
VSLIDEDOWN_VI(REG_V2, REG_V4, 1)
VSLIDEDOWN_VI(REG_V3, REG_V6, 1)
VSLIDEUP_VI(REG_V0, REG_V5, 1)
VSLIDEUP_VI(REG_V1, REG_V7, 1)
VSLIDEUP_VI(REG_V2, REG_V4, 1)
VSLIDEUP_VI(REG_V3, REG_V6, 1)
"mv t0, %[hash]\n\t"
VS4R_V(REG_V0, REG_T0)
#elif defined(WOLFSSL_RISCV_VECTOR_BASE_BIT_MANIPULATION)
VSETIVLI(REG_ZERO, 4, 1, 1, 0b011, 0b001)
"mv t0, %[digest]\n\t"
VL4RE64_V(REG_V0, REG_T0)
VREV8(REG_V0, REG_V0)
VREV8(REG_V2, REG_V2)
"mv t0, %[hash]\n\t"
VS4R_V(REG_V0, REG_T0)
#elif defined(WOLFSSL_RISCV_BASE_BIT_MANIPULATION)
"ld t0, 0(%[digest])\n\t"
"ld t1, 8(%[digest])\n\t"
"ld t2, 16(%[digest])\n\t"
"ld t3, 24(%[digest])\n\t"
"ld s8, 32(%[digest])\n\t"
"ld s9, 40(%[digest])\n\t"
"ld s10, 48(%[digest])\n\t"
"ld s11, 56(%[digest])\n\t"
REV8(REG_T0, REG_T0)
REV8(REG_T1, REG_T1)
REV8(REG_T2, REG_T2)
REV8(REG_T3, REG_T3)
REV8(REG_S8, REG_S8)
REV8(REG_S9, REG_S9)
REV8(REG_S10, REG_S10)
REV8(REG_S11, REG_S11)
"sd t0, 0(%[hash])\n\t"
"sd t1, 8(%[hash])\n\t"
"sd t2, 16(%[hash])\n\t"
"sd t3, 24(%[hash])\n\t"
"sd s8, 32(%[hash])\n\t"
"sd s9, 40(%[hash])\n\t"
"sd s10, 48(%[hash])\n\t"
"sd s11, 56(%[hash])\n\t"
#else
LOAD_DWORD_REV(t0, 0, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(t1, 8, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(t2, 16, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(t3, 24, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(s8, 32, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(s9, 40, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(s10, 48, %[digest], a4, a5, a6, a7)
LOAD_DWORD_REV(s11, 56, %[digest], a4, a5, a6, a7)
"sd t0, 0(%[hash])\n\t"
"sd t1, 8(%[hash])\n\t"
"sd t2, 16(%[hash])\n\t"
"sd t3, 24(%[hash])\n\t"
"sd s8, 32(%[hash])\n\t"
"sd s9, 40(%[hash])\n\t"
"sd s10, 48(%[hash])\n\t"
"sd s11, 56(%[hash])\n\t"
#endif
:
: [digest] "r" (sha512->digest), [hash] "r" (hashRes)
: "cc", "memory", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
"s8", "s9", "s10", "s11", "a4", "a5", "a6", "a7"
);
if (hashRes == hashBuf) {
XMEMCPY(hash, hashBuf, hashLen);
}
}
#ifdef WOLFSSL_SHA512
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
{
int ret = InitSha512(sha512, heap, devId);
if (ret == 0) {
InitSha512_State(sha512);
}
return ret;
}
int wc_InitSha512(wc_Sha512* sha512)
{
return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);
}
void wc_Sha512Free(wc_Sha512* sha512)
{
(void)sha512;
}
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
{
int ret;
if ((sha512 == NULL) || ((data == NULL) && (len != 0))) {
ret = BAD_FUNC_ARG;
}
else {
ret = Sha512Update(sha512, data, len);
}
return ret;
}
static void Sha512FinalRaw(wc_Sha512* sha512, byte* hash, int hashLen)
{
word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)];
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
ByteReverseWords64((word64*)digest, (word64*)sha512->digest,
WC_SHA512_DIGEST_SIZE);
#else
digest[0] = ByteReverseWord64(sha512->digest[3]);
digest[1] = ByteReverseWord64(sha512->digest[2]);
digest[2] = ByteReverseWord64(sha512->digest[7]);
digest[3] = ByteReverseWord64(sha512->digest[6]);
digest[4] = ByteReverseWord64(sha512->digest[1]);
digest[5] = ByteReverseWord64(sha512->digest[0]);
digest[6] = ByteReverseWord64(sha512->digest[5]);
digest[7] = ByteReverseWord64(sha512->digest[4]);
#endif
XMEMCPY(hash, digest, hashLen);
}
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512FinalRaw(sha512, hash, WC_SHA512_DIGEST_SIZE);
}
return ret;
}
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512Final(sha512, hash, WC_SHA512_DIGEST_SIZE);
InitSha512_State(sha512);
}
return ret;
}
int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
{
int ret;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
Sha512Final(&tmpSha512, hash, WC_SHA512_DIGEST_SIZE);
wc_Sha512Free(&tmpSha512);
}
}
return ret;
}
#ifdef WOLFSSL_HASH_FLAGS
int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
{
if (sha512 != NULL) {
sha512->flags = flags;
}
return 0;
}
int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
{
if ((sha512 != NULL) && (flags != NULL)) {
*flags = sha512->flags;
}
return 0;
}
#endif
int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
{
int ret = 0;
if ((src == NULL) || (dst == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
XMEMCPY(dst, src, sizeof(wc_Sha512));
}
return ret;
}
#ifdef OPENSSL_EXTRA
int wc_Sha512Transform(wc_Sha512* sha512, const unsigned char* data)
{
int ret = 0;
if ((sha512 == NULL) || (data == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
ByteReverseWords((word32*)sha512->buffer, (word32*)data, WC_SHA512_BLOCK_SIZE);
Sha512Transform(sha512, (byte*)sha512->buffer, 1);
}
return ret;
}
#endif
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
int wc_Sha512HashBlock(wc_Sha512* sha512, const unsigned char* data,
unsigned char* hash)
{
int ret = 0;
if ((sha512 == NULL) || (data == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512Transform(sha512, data, 1);
if (hash != NULL) {
word32* hash32 = (word32*)hash;
word32* digest = (word32*)sha512->digest;
hash32[0] = ByteReverseWord32(digest[0]);
hash32[1] = ByteReverseWord32(digest[1]);
hash32[2] = ByteReverseWord32(digest[2]);
hash32[3] = ByteReverseWord32(digest[3]);
hash32[4] = ByteReverseWord32(digest[4]);
hash32[5] = ByteReverseWord32(digest[5]);
hash32[6] = ByteReverseWord32(digest[6]);
hash32[7] = ByteReverseWord32(digest[7]);
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
sha512->digest[0] = 0x6A09E667L;
sha512->digest[1] = 0xBB67AE85L;
sha512->digest[2] = 0x3C6EF372L;
sha512->digest[3] = 0xA54FF53AL;
sha512->digest[4] = 0x510E527FL;
sha512->digest[5] = 0x9B05688CL;
sha512->digest[6] = 0x1F83D9ABL;
sha512->digest[7] = 0x5BE0CD19L;
#else
sha512->digest[0] = 0x9B05688CL;
sha512->digest[1] = 0x510E527FL;
sha512->digest[2] = 0xBB67AE85L;
sha512->digest[3] = 0x6A09E667L;
sha512->digest[4] = 0x5BE0CD19L;
sha512->digest[5] = 0x1F83D9ABL;
sha512->digest[6] = 0xA54FF53AL;
sha512->digest[7] = 0x3C6EF372L;
#endif
}
}
return ret;
}
#endif
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
#if !defined(WOLFSSL_NOSHA512_224)
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
{
int ret = InitSha512(sha512, heap, devId);
if (ret == 0) {
InitSha512_224_State(sha512);
}
return ret;
}
int wc_InitSha512_224(wc_Sha512* sha512)
{
return wc_InitSha512_224_ex(sha512, NULL, INVALID_DEVID);
}
int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len)
{
return wc_Sha512Update(sha512, data, len);
}
int wc_Sha512_224FinalRaw(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512FinalRaw(sha512, hash, WC_SHA512_224_DIGEST_SIZE);
}
return ret;
}
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE);
InitSha512_224_State(sha512);
}
return ret;
}
void wc_Sha512_224Free(wc_Sha512* sha512)
{
wc_Sha512Free(sha512);
}
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
{
int ret;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
Sha512Final(&tmpSha512, hash, WC_SHA512_224_DIGEST_SIZE);
wc_Sha512Free(&tmpSha512);
}
}
return ret;
}
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
{
return wc_Sha512Copy(src, dst);
}
#ifdef WOLFSSL_HASH_FLAGS
int wc_Sha512_224SetFlags(wc_Sha512* sha512, word32 flags)
{
return wc_Sha512SetFlags(sha512, flags);
}
int wc_Sha512_224GetFlags(wc_Sha512* sha512, word32* flags)
{
return wc_Sha512GetFlags(sha512, flags);
}
#endif
#if defined(OPENSSL_EXTRA)
int wc_Sha512_224Transform(wc_Sha512* sha512, const unsigned char* data)
{
return wc_Sha512Transform(sha512, data);
}
#endif
#endif
#if !defined(WOLFSSL_NOSHA512_256)
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
{
int ret = InitSha512(sha512, heap, devId);
if (ret == 0) {
InitSha512_256_State(sha512);
}
return ret;
}
int wc_InitSha512_256(wc_Sha512* sha512)
{
return wc_InitSha512_256_ex(sha512, NULL, INVALID_DEVID);
}
int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len)
{
return wc_Sha512Update(sha512, data, len);
}
int wc_Sha512_256FinalRaw(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512FinalRaw(sha512, hash, WC_SHA512_256_DIGEST_SIZE);
}
return ret;
}
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE);
InitSha512_256_State(sha512);
}
return ret;
}
void wc_Sha512_256Free(wc_Sha512* sha512)
{
wc_Sha512Free(sha512);
}
int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
{
int ret;
if ((sha512 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
wc_Sha512 tmpSha512;
XMEMSET(&tmpSha512, 0, sizeof(tmpSha512));
ret = wc_Sha512Copy(sha512, &tmpSha512);
if (ret == 0) {
Sha512Final(&tmpSha512, hash, WC_SHA512_256_DIGEST_SIZE);
wc_Sha512Free(&tmpSha512);
}
}
return ret;
}
int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
{
return wc_Sha512Copy(src, dst);
}
#ifdef WOLFSSL_HASH_FLAGS
int wc_Sha512_256SetFlags(wc_Sha512* sha512, word32 flags)
{
return wc_Sha512SetFlags(sha512, flags);
}
int wc_Sha512_256GetFlags(wc_Sha512* sha512, word32* flags)
{
return wc_Sha512GetFlags(sha512, flags);
}
#endif
#if defined(OPENSSL_EXTRA)
int wc_Sha512_256Transform(wc_Sha512* sha512, const unsigned char* data)
{
return wc_Sha512Transform(sha512, data);
}
#endif
#endif
#endif
#endif
#ifdef WOLFSSL_SHA384
static void InitSha384(wc_Sha384* sha384)
{
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
sha384->digest[1] = W64LIT(0x629a292a367cd507);
sha384->digest[2] = W64LIT(0x9159015a3070dd17);
sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
sha384->digest[4] = W64LIT(0x67332667ffc00b31);
sha384->digest[5] = W64LIT(0x8eb44a8768581511);
sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
#else
sha384->digest[0] = W64LIT(0x8eb44a8768581511);
sha384->digest[1] = W64LIT(0x67332667ffc00b31);
sha384->digest[2] = W64LIT(0x629a292a367cd507);
sha384->digest[3] = W64LIT(0xcbbb9d5dc1059ed8);
sha384->digest[4] = W64LIT(0x47b5481dbefa4fa4);
sha384->digest[5] = W64LIT(0xdb0c2e0d64f98fa7);
sha384->digest[6] = W64LIT(0x152fecd8f70e5939);
sha384->digest[7] = W64LIT(0x9159015a3070dd17);
#endif
sha384->buffLen = 0;
sha384->loLen = 0;
sha384->hiLen = 0;
}
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
{
int ret = InitSha512(sha384, heap, devId);
if (ret == 0) {
InitSha384(sha384);
}
return ret;
}
int wc_InitSha384(wc_Sha384* sha384)
{
return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID);
}
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
{
int ret;
if ((sha384 == NULL) || ((data == NULL) && (len > 0))) {
ret = BAD_FUNC_ARG;
}
else {
ret = Sha512Update((wc_Sha512 *)sha384, data, len);
}
return ret;
}
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
{
word64 digest[WC_SHA384_DIGEST_SIZE / sizeof(word64)];
if (sha384 == NULL || hash == NULL) {
return BAD_FUNC_ARG;
}
#ifndef WOLFSSL_RISCV_VECTOR_CRYPTO_ASM
ByteReverseWords64((word64*)digest, (word64*)sha384->digest,
WC_SHA384_DIGEST_SIZE);
#else
digest[0] = ByteReverseWord64(sha384->digest[3]);
digest[1] = ByteReverseWord64(sha384->digest[2]);
digest[2] = ByteReverseWord64(sha384->digest[7]);
digest[3] = ByteReverseWord64(sha384->digest[6]);
digest[4] = ByteReverseWord64(sha384->digest[1]);
digest[5] = ByteReverseWord64(sha384->digest[0]);
#endif
XMEMCPY(hash, digest, WC_SHA384_DIGEST_SIZE);
return 0;
}
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
{
int ret = 0;
if ((sha384 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
Sha512Final((wc_Sha512*)sha384, hash, WC_SHA384_DIGEST_SIZE);
InitSha384(sha384);
}
return ret;
}
void wc_Sha384Free(wc_Sha384* sha384)
{
(void)sha384;
}
int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
{
int ret;
if ((sha384 == NULL) || (hash == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
wc_Sha384 tmpSha384;
XMEMSET(&tmpSha384, 0, sizeof(tmpSha384));
ret = wc_Sha384Copy(sha384, &tmpSha384);
if (ret == 0) {
ret = wc_Sha384Final(&tmpSha384, hash);
}
}
return ret;
}
#ifdef WOLFSSL_HASH_FLAGS
int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
{
if (sha384 != NULL) {
sha384->flags = flags;
}
return 0;
}
int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
{
if ((sha384 != NULL) && (flags != NULL)) {
*flags = sha384->flags;
}
return 0;
}
#endif
int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
{
int ret = 0;
if ((src == NULL) || (dst == NULL)) {
ret = BAD_FUNC_ARG;
}
else {
XMEMCPY(dst, src, sizeof(wc_Sha384));
}
return ret;
}
#endif
#endif
#endif