322 lines
7.6 KiB
Diff
322 lines
7.6 KiB
Diff
From c4222d2434eb877fc077cdb338ac22ab6779f412 Mon Sep 17 00:00:00 2001
|
|
From: godcansee <liu332084460@foxmail.com>
|
|
Date: Tue, 27 Sep 2022 19:55:55 +0800
|
|
Subject: [PATCH 1/4] nss add implement of SM3 digest algorithm
|
|
|
|
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
|
|
---
|
|
lib/freebl/sm3.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
lib/freebl/sm3.h | 19 ++++
|
|
2 files changed, 293 insertions(+)
|
|
create mode 100644 lib/freebl/sm3.c
|
|
create mode 100644 lib/freebl/sm3.h
|
|
|
|
diff --git a/lib/freebl/sm3.c b/lib/freebl/sm3.c
|
|
new file mode 100644
|
|
index 0000000..27751ff
|
|
--- /dev/null
|
|
+++ b/lib/freebl/sm3.c
|
|
@@ -0,0 +1,274 @@
|
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
+
|
|
+#ifdef FREEBL_NO_DEPEND
|
|
+#include "stubs.h"
|
|
+#endif
|
|
+
|
|
+#include "prerr.h"
|
|
+#include "prtypes.h"
|
|
+#include "prlong.h"
|
|
+#include "secport.h"
|
|
+#include "secerr.h"
|
|
+#include "blapi.h"
|
|
+#include "sm3.h"
|
|
+
|
|
+#define ROTATE(a,n) (((a) << (n)) | (((a) & 0xffffffff) >> (32 - (n))))
|
|
+
|
|
+#define FF0(X,Y,Z) (X ^ Y ^ Z)
|
|
+#define GG0(X,Y,Z) (X ^ Y ^ Z)
|
|
+
|
|
+#define FF16(X,Y,Z) ((X & Y) | (X & Z) | (Y & Z))
|
|
+#define GG16(X,Y,Z) ((X & Y) | ((~X) & Z))
|
|
+
|
|
+#define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23))
|
|
+
|
|
+#define Get_32(l, c) ((l) = (PRUint32)(((*((PRUint8*)(c))) << 24) | \
|
|
+ ((*((PRUint8*)(c) + 1)) << 16) | \
|
|
+ ((*((PRUint8*)(c) + 2)) << 8) | \
|
|
+ ((*((PRUint8*)(c) + 3)))))
|
|
+
|
|
+#define Put_32(p, N) ((*((PRUint8*)(p))) = (PRUint8)((N) >> 24), \
|
|
+ (*((PRUint8*)(p) + 1)) = (PRUint8)((N) >> 16), \
|
|
+ (*((PRUint8*)(p) + 2)) = (PRUint8)((N) >> 8), \
|
|
+ (*((PRUint8*)(p) + 3)) = (PRUint8)(N))
|
|
+
|
|
+void processOfSM3(SM3Context *ctx, const unsigned char *p) {
|
|
+ int j;
|
|
+ PRUint32 W[68];
|
|
+ PRUint32 A, B, C, D, E, F, G, H;
|
|
+ PRUint32 SS1, SS2, TT1, TT2;
|
|
+
|
|
+ A = ctx->A;
|
|
+ B = ctx->B;
|
|
+ C = ctx->C;
|
|
+ D = ctx->D;
|
|
+ E = ctx->E;
|
|
+ F = ctx->F;
|
|
+ G = ctx->G;
|
|
+ H = ctx->H;
|
|
+
|
|
+ for (j = 0; j < 16; j++)
|
|
+ Get_32(W[j], p + 4 * j);
|
|
+
|
|
+ for (j = 16; j <= 67; j++)
|
|
+ W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROTATE(W[j - 3], 15)) ^ ROTATE(W[j - 13], 7) ^ W[j - 6];
|
|
+
|
|
+ for (j = 0; j < 16; j++) {
|
|
+ SS1 = ROTATE(A, 12);
|
|
+ SS1 = SS1 + E;
|
|
+ SS1 = SS1 + ROTATE(0x79cc4519UL, j);
|
|
+ SS1 = ROTATE(SS1, 7);
|
|
+ SS2 = SS1 ^ ROTATE(A, 12);
|
|
+ TT1 = FF0(A, B, C) + D;
|
|
+ TT1 = TT1 + SS2;
|
|
+ TT1 = TT1 + (W[j] ^ W[j + 4]);
|
|
+ TT2 = GG0(E, F, G) + H;
|
|
+ TT2 = TT2 + SS1;
|
|
+ TT2 = TT2 + W[j];
|
|
+ D = C;
|
|
+ C = ROTATE(B, 9);
|
|
+ B = A;
|
|
+ A = TT1;
|
|
+ H = G;
|
|
+ G = ROTATE(F, 19);
|
|
+ F = E;
|
|
+ E = TT2 ^ ROTATE(TT2, 9) ^ ROTATE(TT2, 17);
|
|
+ }
|
|
+
|
|
+ for (j = 16; j < 64; j++) {
|
|
+ SS1 = ROTATE(A, 12);
|
|
+ SS1 = SS1 + E;
|
|
+ SS1 = SS1 + ROTATE(0x7a879d8aUL, j & 0x1f);
|
|
+ SS1 = ROTATE(SS1, 7);
|
|
+ SS2 = SS1 ^ ROTATE(A, 12);
|
|
+ TT1 = FF16(A, B, C) + D;
|
|
+ TT1 = TT1 + SS2;
|
|
+ TT1 = TT1 + (W[j] ^ W[j + 4]);
|
|
+ TT2 = GG16(E, F, G) + H;
|
|
+ TT2 = TT2 + SS1;
|
|
+ TT2 = TT2 + W[j];
|
|
+ D = C;
|
|
+ C = ROTATE(B, 9);
|
|
+ B = A;
|
|
+ A = TT1;
|
|
+ H = G;
|
|
+ G = ROTATE(F, 19);
|
|
+ F = E;
|
|
+ E = TT2 ^ ROTATE(TT2, 9) ^ ROTATE(TT2, 17);
|
|
+ }
|
|
+
|
|
+ ctx->A ^= A;
|
|
+ ctx->B ^= B;
|
|
+ ctx->C ^= C;
|
|
+ ctx->D ^= D;
|
|
+ ctx->E ^= E;
|
|
+ ctx->F ^= F;
|
|
+ ctx->G ^= G;
|
|
+ ctx->H ^= H;
|
|
+}
|
|
+
|
|
+SM3Context *
|
|
+SM3_NewContext(void)
|
|
+{
|
|
+ SM3Context *ctx = PORT_New(SM3Context);
|
|
+ return ctx;
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_DestroyContext(SM3Context *ctx, PRBool freeit)
|
|
+{
|
|
+ memset(ctx, 0, sizeof *ctx);
|
|
+ if (freeit) {
|
|
+ PORT_Free(ctx);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_Begin(SM3Context *ctx)
|
|
+{
|
|
+ memset(ctx, 0, sizeof(SM3Context));
|
|
+ ctx->A = 0x7380166fUL;
|
|
+ ctx->B = 0x4914b2b9UL;
|
|
+ ctx->C = 0x172442d7UL;
|
|
+ ctx->D = 0xda8a0600UL;
|
|
+ ctx->E = 0xa96f30bcUL;
|
|
+ ctx->F = 0x163138aaUL;
|
|
+ ctx->G = 0xe38dee4dUL;
|
|
+ ctx->H = 0xb0fb0e4eUL;
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_Update(SM3Context *ctx, const unsigned char *input,
|
|
+ unsigned int inputLen)
|
|
+{
|
|
+ PRUint32 l, n, rest;
|
|
+ PRUint8 *p;
|
|
+
|
|
+ l = (ctx->Nl + (inputLen << 3)) & 0xffffffff;
|
|
+ if (l < ctx->Nl)
|
|
+ ctx->Nh++;
|
|
+
|
|
+ ctx->Nl = l;
|
|
+ ctx->Nh += (inputLen >> 29);
|
|
+ p = ctx->data;
|
|
+ n = ctx->num;
|
|
+
|
|
+ rest = 64 - n;
|
|
+ if (n) {
|
|
+ if (inputLen >= rest) {
|
|
+ memcpy(p + n, input, rest);
|
|
+ input += rest;
|
|
+ inputLen -= rest;
|
|
+ ctx->num = 0;
|
|
+ processOfSM3(ctx, p);
|
|
+ memset(p, 0, 64);
|
|
+ } else {
|
|
+ memcpy(p + n, input, inputLen);
|
|
+ ctx->num += inputLen;
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ while (inputLen >= 64) {
|
|
+ processOfSM3(ctx, input);
|
|
+ input += 64;
|
|
+ inputLen -= 64;
|
|
+ }
|
|
+
|
|
+ if (inputLen) {
|
|
+ ctx->num = inputLen;
|
|
+ memcpy(ctx->data, input, inputLen);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_End(SM3Context *ctx, unsigned char *digest,
|
|
+ unsigned int *digestLen, unsigned int maxDigestLen)
|
|
+{
|
|
+ PRUint32 n = ctx->num;
|
|
+
|
|
+ if (maxDigestLen < SM3_LENGTH) {
|
|
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ctx->data[n] = 0x80;
|
|
+
|
|
+ if (n >= 56) {
|
|
+ memset(ctx->data + n + 1, 0, 64 - n - 1);
|
|
+ processOfSM3(ctx, ctx->data);
|
|
+ memset(ctx->data, 0, 64);
|
|
+ }
|
|
+
|
|
+ Put_32(&ctx->data[56], ctx->Nh);
|
|
+ Put_32(&ctx->data[60], ctx->Nl);
|
|
+ processOfSM3(ctx, ctx->data);
|
|
+
|
|
+ Put_32(digest, ctx->A);
|
|
+ Put_32(digest + 4, ctx->B);
|
|
+ Put_32(digest + 8, ctx->C);
|
|
+ Put_32(digest + 12, ctx->D);
|
|
+ Put_32(digest + 16, ctx->E);
|
|
+ Put_32(digest + 20, ctx->F);
|
|
+ Put_32(digest + 24, ctx->G);
|
|
+ Put_32(digest + 28, ctx->H);
|
|
+
|
|
+ if (digestLen)
|
|
+ *digestLen = SM3_LENGTH;
|
|
+}
|
|
+
|
|
+SECStatus
|
|
+SM3_HashBuf(unsigned char *dest, const unsigned char *src,
|
|
+ PRUint32 src_length)
|
|
+{
|
|
+ SM3Context ctx;
|
|
+ unsigned int outLen;
|
|
+
|
|
+ SM3_Begin(&ctx);
|
|
+ SM3_Update(&ctx, src, src_length);
|
|
+ SM3_End(&ctx, dest, &outLen, SM3_LENGTH);
|
|
+ memset(&ctx, 0, sizeof ctx);
|
|
+
|
|
+ return SECSuccess;
|
|
+}
|
|
+
|
|
+SECStatus
|
|
+SM3_Hash(unsigned char *dest, const char *src)
|
|
+{
|
|
+ return SM3_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_TraceState(SM3Context *ctx)
|
|
+{
|
|
+}
|
|
+
|
|
+unsigned int
|
|
+SM3_FlattenSize(SM3Context *ctx)
|
|
+{
|
|
+ return sizeof *ctx;
|
|
+}
|
|
+
|
|
+SECStatus
|
|
+SM3_Flatten(SM3Context *ctx, unsigned char *space)
|
|
+{
|
|
+ PORT_Memcpy(space, ctx, sizeof *ctx);
|
|
+ return SECSuccess;
|
|
+}
|
|
+
|
|
+SM3Context *
|
|
+SM3_Resurrect(unsigned char *space, void *arg)
|
|
+{
|
|
+ SM3Context *ctx = SM3_NewContext();
|
|
+ if (ctx)
|
|
+ PORT_Memcpy(ctx, space, sizeof *ctx);
|
|
+ return ctx;
|
|
+}
|
|
+
|
|
+void
|
|
+SM3_Clone(SM3Context *dest, SM3Context *src)
|
|
+{
|
|
+ memcpy(dest, src, sizeof *dest);
|
|
+}
|
|
diff --git a/lib/freebl/sm3.h b/lib/freebl/sm3.h
|
|
new file mode 100644
|
|
index 0000000..83d787f
|
|
--- /dev/null
|
|
+++ b/lib/freebl/sm3.h
|
|
@@ -0,0 +1,19 @@
|
|
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
+
|
|
+#ifndef _SM3_H_
|
|
+#define _SM3_H_
|
|
+
|
|
+#include "prtypes.h"
|
|
+
|
|
+struct SM3ContextStr {
|
|
+ PRUint32 A, B, C, D, E, F, G, H;
|
|
+ PRUint32 Nl, Nh;
|
|
+ PRUint8 data[64];
|
|
+ PRUint32 num;
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+#endif /* _SM3_H_ */
|
|
--
|
|
2.33.0
|
|
|