From 633bdaae41f18da4bee5c4464c917b76f7ed9313 Mon Sep 17 00:00:00 2001 From: godcansee Date: Sun, 16 Oct 2022 04:58:00 +0800 Subject: [PATCH 1/4] nss-add-implement-of-SM3-digest-algorithm Co-authored-by:Huaxin Lu --- nss/lib/freebl/sm3.c | 285 +++++++++++++++++++++++++++++++++++++++++++ nss/lib/freebl/sm3.h | 23 ++++ 2 files changed, 308 insertions(+) create mode 100644 nss/lib/freebl/sm3.c create mode 100644 nss/lib/freebl/sm3.h diff --git a/nss/lib/freebl/sm3.c b/nss/lib/freebl/sm3.c new file mode 100644 index 0000000..7c1137f --- /dev/null +++ b/nss/lib/freebl/sm3.c @@ -0,0 +1,285 @@ +/* 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 "prtypes.h" +#include "prlong.h" +#include "secport.h" +#include "blapi.h" +#include "secerr.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_N(l, c, n) (l = (PRUint32)(((*(PRUint8*)(c + n)) << 24)|((*(PRUint8*)(c + n + 1)) << 16)|((*(PRUint8*)(c + n + 2)) << 8)|((*(PRUint8*)(c + n + 3))))) +#define Put_N(p, N, n) ((*(PRUint8*)(p + n)) = N) +#define Put_32(p, N, n) \ + ((*(PRUint8*)(p + n)) = (PRUint8)((N) >> 24), \ + (*(PRUint8*)(p + n + 1)) = (PRUint8)((N) >> 16), \ + (*(PRUint8*)(p + n + 2)) = (PRUint8)((N) >> 8), \ + (*(PRUint8*)(p + n + 3)) = (PRUint8)(N)) + +struct SM3ContextStr { + PRUint32 A, B, C, D, E, F, G, H; + PRUint32 Nl, Nh; + PRUint8 data[64]; + PRUint32 num; +}; + +typedef struct SM3ContextStr SM3Context; + +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_N(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) +{ + unsigned int l; + unsigned char *p; + unsigned int n, rest; + + l = (unsigned int)((ctx->Nl + (inputLen << 3)) & 0xffffffff); + if (l < (unsigned int)ctx->Nl) + ctx->Nh++; + ctx->Nl = l; + ctx->Nh += inputLen>>29; + p = (unsigned char *)ctx->data; + n = (unsigned int)ctx->num; + rest = 64 - n; + + if (n != 0) { + 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 += (unsigned int)inputLen; + return; + } + } + + while (inputLen >= 64) { + processOfSM3(ctx, input); + input += 64; + inputLen -= 64; + } + + if (inputLen > 0) { + ctx->num = (unsigned int)inputLen; + memcpy(ctx->data, input, inputLen); + } +} + +void +SM3_End(SM3Context *ctx, unsigned char *digest, + unsigned int *digestLen, unsigned int maxDigestLen) +{ + unsigned int n = ctx->num; + + if (maxDigestLen < SM3_LENGTH) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return; + } + + if (n >= 56) { + ctx->data[n] = 0x80; + n++; + memset(ctx->data + n, 0, 64 - n); + processOfSM3(ctx, ctx->data); + memset(ctx->data, 0, 64); + Put_32(ctx->data, ctx->Nh, 56); + Put_32(ctx->data, ctx->Nl, 60); + processOfSM3(ctx, ctx->data); + memset(ctx->data, 0, 64); + } else { + ctx->data[n] = 0x80; + Put_32(ctx->data, ctx->Nh, 56); + Put_32(ctx->data, ctx->Nl, 60); + processOfSM3(ctx, ctx->data); + memset(ctx->data, 0, 64); + } + + Put_32(digest, ctx->A, 0); + Put_32(digest, ctx->B, 4); + Put_32(digest, ctx->C, 8); + Put_32(digest, ctx->D, 12); + Put_32(digest, ctx->E, 16); + Put_32(digest, ctx->F, 20); + Put_32(digest, ctx->G, 24); + Put_32(digest, ctx->H, 28); + + 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/nss/lib/freebl/sm3.h b/nss/lib/freebl/sm3.h new file mode 100644 index 0000000..c08ae1e --- /dev/null +++ b/nss/lib/freebl/sm3.h @@ -0,0 +1,23 @@ +/* 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" + +SM3Context *SM3_NewContext(void); +void SM3_DestroyContext(SM3Context *ctx, PRBool freeit); +void SM3_Begin(SM3Context *ctx); +void SM3_Update(SM3Context *ctx, const unsigned char *input, unsigned int inputLen); +void SM3_End(SM3Context *ctx, unsigned char *digest, unsigned int *digestLen, unsigned int maxDigestLen); +SECStatus SM3_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length); +SECStatus SM3_Hash(unsigned char *dest, const char *src); +void SM3_TraceState(SM3Context *ctx); +unsigned int SM3_FlattenSize(SM3Context *ctx); +SECStatus SM3_Flatten(SM3Context *ctx, unsigned char *space); +SM3Context *SM3_Resurrect(unsigned char *space, void *arg); +void SM3_Clone(SM3Context *dest, SM3Context *src); + +#endif /* _SM3_H_ */ -- 2.33.0