diff --git a/nss-add-implement-of-SM2-signature-algorithm.patch b/nss-add-implement-of-SM2-signature-algorithm.patch new file mode 100644 index 0000000000000000000000000000000000000000..2705cd543d4214e4d730e33af7bbb9be4f20e69d --- /dev/null +++ b/nss-add-implement-of-SM2-signature-algorithm.patch @@ -0,0 +1,876 @@ +From 347a578fa37bb49aee76d8435fd5f0f34875a34e Mon Sep 17 00:00:00 2001 +From: godcansee +Date: Sun, 16 Oct 2022 05:00:04 +0800 +Subject: [PATCH 2/4] nss add implement of SM2 signature algorithm + +Co-authored-by:Huaxin Lu +--- + nss/lib/freebl/sm2.c | 823 +++++++++++++++++++++++++++++++++++++++++++ + nss/lib/freebl/sm2.h | 23 ++ + 2 files changed, 846 insertions(+) + create mode 100644 nss/lib/freebl/sm2.c + create mode 100644 nss/lib/freebl/sm2.h + +diff --git a/nss/lib/freebl/sm2.c b/nss/lib/freebl/sm2.c +new file mode 100644 +index 0000000..0ea85bc +--- /dev/null ++++ b/nss/lib/freebl/sm2.c +@@ -0,0 +1,823 @@ ++/* ++ * Copyright 2022 The GmSSL Project. All Rights Reserved. ++ * ++ * Licensed under the Apache License, Version 2.0 (the License); you may ++ * not use this file except in compliance with the License. ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ */ ++ ++#include "sm2.h" ++ ++ ++#define GETU32(p) ((PRUint32)(p)[0] << 24 | (PRUint32)(p)[1] << 16 | (PRUint32)(p)[2] << 8 | (PRUint32)(p)[3]) ++#define PUTU32(p,V) ((p)[0] = (PRUint8)((V) >> 24), (p)[1] = (PRUint8)((V) >> 16), (p)[2] = (PRUint8)((V) >> 8), (p)[3] = (PRUint8)(V)) ++ ++#define sm2_bn_init(r) memset((r),0,sizeof(SM2_BN)) ++#define sm2_bn_set_zero(r) memset((r),0,sizeof(SM2_BN)) ++#define sm2_bn_set_one(r) sm2_bn_set_word((r),1) ++#define sm2_bn_copy(r,a) memcpy((r),(a),sizeof(SM2_BN)) ++#define sm2_bn_clean(r) memset((r),0,sizeof(SM2_BN)) ++ ++#define sm2_fp_init(r) sm2_bn_init(r) ++#define sm2_fp_set_zero(r) sm2_bn_set_zero(r) ++#define sm2_fp_set_one(r) sm2_bn_set_one(r) ++#define sm2_fp_copy(r,a) sm2_bn_copy(r,a) ++#define sm2_fp_clean(r) sm2_bn_clean(r) ++ ++#define sm2_fn_init(r) sm2_bn_init(r) ++#define sm2_fn_set_zero(r) sm2_bn_set_zero(r) ++#define sm2_fn_set_one(r) sm2_bn_set_one(r) ++#define sm2_fn_copy(r,a) sm2_bn_copy(r,a) ++#define sm2_fn_clean(r) sm2_bn_clean(r) ++ ++#define sm2_jacobian_point_set_infinity(R) sm2_jacobian_point_init(R) ++#define sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(SM2_JACOBIAN_POINT)) ++ ++#define SM2_POINT_MAX_SIZE (2 + 65) ++ ++typedef PRUint64 SM2_BN[8]; ++ ++typedef SM2_BN SM2_Fp; ++typedef SM2_BN SM2_Fn; ++ ++typedef struct { ++ SM2_BN X; ++ SM2_BN Y; ++ SM2_BN Z; ++} SM2_JACOBIAN_POINT; ++ ++typedef struct { ++ PRUint8 x[32]; ++ PRUint8 y[32]; ++} SM2_POINT; ++ ++const SM2_BN SM2_P = { ++ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, ++ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, ++}; ++ ++const SM2_BN SM2_A = { ++ 0xfffffffc, 0xffffffff, 0x00000000, 0xffffffff, ++ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, ++}; ++ ++const SM2_BN SM2_B = { ++ 0x4d940e93, 0xddbcbd41, 0x15ab8f92, 0xf39789f5, ++ 0xcf6509a7, 0x4d5a9e4b, 0x9d9f5e34, 0x28e9fa9e, ++}; ++ ++const SM2_JACOBIAN_POINT _SM2_G = { ++ { ++ 0x334c74c7, 0x715a4589, 0xf2660be1, 0x8fe30bbf, ++ 0x6a39c994, 0x5f990446, 0x1f198119, 0x32c4ae2c, ++ }, ++ { ++ 0x2139f0a0, 0x02df32e5, 0xc62a4740, 0xd0a9877c, ++ 0x6b692153, 0x59bdcee3, 0xf4f6779c, 0xbc3736a2, ++ }, ++ { ++ 1, 0, 0, 0, 0, 0, 0, 0, ++ }, ++}; ++const SM2_JACOBIAN_POINT* SM2_G = &_SM2_G; ++ ++const SM2_BN SM2_N = { ++ 0x39d54123, 0x53bbf409, 0x21c6052b, 0x7203df6b, ++ 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, ++}; ++ ++const SM2_BN SM2_ONE = { 1,0,0,0,0,0,0,0 }; ++const SM2_BN SM2_TWO = { 2,0,0,0,0,0,0,0 }; ++const SM2_BN SM2_THREE = { 3,0,0,0,0,0,0,0 }; ++ ++ ++int rand_bytes(PRUint8* buf, int len) ++{ ++ FILE* fp; ++ if (!buf) { ++ return -1; ++ } ++ if (len > 4096) { ++ return -1; ++ } ++ if (!len) { ++ return 0; ++ } ++ ++ if (!(fp = fopen("/dev/urandom", "rb"))) { ++ return -1; ++ } ++ if (fread(buf, 1, len, fp) != len) { ++ fclose(fp); ++ return -1; ++ } ++ fclose(fp); ++ return 1; ++} ++ ++int sm2_bn_is_zero(const SM2_BN a) ++{ ++ int i; ++ for (i = 0; i < 8; i++) { ++ if (a[i] != 0) ++ return 0; ++ } ++ return 1; ++} ++ ++int sm2_bn_is_one(const SM2_BN a) ++{ ++ int i; ++ if (a[0] != 1) ++ return 0; ++ for (i = 1; i < 8; i++) { ++ if (a[i] != 0) ++ return 0; ++ } ++ return 1; ++} ++ ++void sm2_bn_to_bytes(const SM2_BN a, PRUint8 out[32]) ++{ ++ int i; ++ for (i = 7; i >= 0; i--) { ++ PRUint32 ai = (PRUint32)a[i]; ++ PUTU32(out, ai); ++ out += sizeof(PRUint32); ++ } ++} ++ ++void sm2_bn_from_bytes(SM2_BN r, const PRUint8 in[32]) ++{ ++ int i; ++ for (i = 7; i >= 0; i--) { ++ r[i] = GETU32(in); ++ in += sizeof(PRUint32); ++ } ++} ++ ++void sm2_bn_to_bits(const SM2_BN a, char bits[256]) ++{ ++ int i, j; ++ for (i = 7; i >= 0; i--) { ++ PRUint32 w = a[i]; ++ for (j = 0; j < 32; j++) { ++ *bits++ = (w & 0x80000000) ? '1' : '0'; ++ w <<= 1; ++ } ++ } ++} ++ ++int sm2_bn_cmp(const SM2_BN a, const SM2_BN b) ++{ ++ int i; ++ for (i = 7; i >= 0; i--) { ++ if (a[i] > b[i]) ++ return 1; ++ if (a[i] < b[i]) ++ return -1; ++ } ++ return 0; ++} ++ ++void sm2_bn_set_word(SM2_BN r, PRUint32 a) ++{ ++ int i; ++ r[0] = a; ++ for (i = 1; i < 8; i++) { ++ r[i] = 0; ++ } ++} ++ ++void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b) ++{ ++ int i; ++ r[0] = a[0] + b[0]; ++ ++ for (i = 1; i < 8; i++) { ++ r[i] = a[i] + b[i] + (r[i - 1] >> 32); ++ } ++ for (i = 0; i < 7; i++) { ++ r[i] &= 0xffffffff; ++ } ++} ++ ++void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b) ++{ ++ int i; ++ SM2_BN r; ++ r[0] = ((PRUint64)1 << 32) + a[0] - b[0]; ++ for (i = 1; i < 7; i++) { ++ r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); ++ r[i - 1] &= 0xffffffff; ++ } ++ r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; ++ r[i - 1] &= 0xffffffff; ++ sm2_bn_copy(ret, r); ++} ++ ++void sm2_bn_rand_range(SM2_BN r, const SM2_BN range) ++{ ++ PRUint8 buf[32]; ++ do { ++ (void)rand_bytes(buf, sizeof(buf)); ++ sm2_bn_from_bytes(r, buf); ++ } while (sm2_bn_cmp(r, range) >= 0); ++} ++ ++void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) ++{ ++ sm2_bn_add(r, a, b); ++ if (sm2_bn_cmp(r, SM2_P) >= 0) { ++ sm2_bn_sub(r, r, SM2_P); ++ } ++} ++ ++void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) ++{ ++ if (sm2_bn_cmp(a, b) >= 0) { ++ sm2_bn_sub(r, a, b); ++ } ++ else { ++ SM2_BN t; ++ sm2_bn_sub(t, SM2_P, b); ++ sm2_bn_add(r, t, a); ++ } ++} ++ ++void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a) ++{ ++ sm2_fp_add(r, a, a); ++} ++ ++void sm2_fp_tri(SM2_Fp r, const SM2_Fp a) ++{ ++ SM2_BN t; ++ sm2_fp_dbl(t, a); ++ sm2_fp_add(r, t, a); ++} ++ ++void sm2_fp_div2(SM2_Fp r, const SM2_Fp a) ++{ ++ int i; ++ sm2_bn_copy(r, a); ++ if (r[0] & 0x01) { ++ sm2_bn_add(r, r, SM2_P); ++ } ++ for (i = 0; i < 7; i++) { ++ r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); ++ } ++ r[i] >>= 1; ++} ++ ++void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) ++{ ++ int i, j; ++ PRUint64 s[16] = { 0 }; ++ SM2_BN d = { 0 }; ++ PRUint64 u; ++ ++ for (i = 0; i < 8; i++) { ++ u = 0; ++ for (j = 0; j < 8; j++) { ++ u = s[i + j] + a[i] * b[j] + u; ++ s[i + j] = u & 0xffffffff; ++ u >>= 32; ++ } ++ s[i + 8] = u; ++ } ++ ++ r[0] = s[0] + s[8] + s[9] + s[10] + s[11] + s[12] + ((s[13] + s[14] + s[15]) << 1); ++ r[1] = s[1] + s[9] + s[10] + s[11] + s[12] + s[13] + ((s[14] + s[15]) << 1); ++ r[2] = s[2]; ++ r[3] = s[3] + s[8] + s[11] + s[12] + s[14] + s[15] + (s[13] << 1); ++ r[4] = s[4] + s[9] + s[12] + s[13] + s[15] + (s[14] << 1); ++ r[5] = s[5] + s[10] + s[13] + s[14] + (s[15] << 1); ++ r[6] = s[6] + s[11] + s[14] + s[15]; ++ r[7] = s[7] + s[8] + s[9] + s[10] + s[11] + s[15] + ((s[12] + s[13] + s[14] + s[15]) << 1); ++ ++ for (i = 1; i < 8; i++) { ++ r[i] += r[i - 1] >> 32; ++ r[i - 1] &= 0xffffffff; ++ } ++ ++ d[2] = s[8] + s[9] + s[13] + s[14]; ++ d[3] = d[2] >> 32; ++ d[2] &= 0xffffffff; ++ sm2_bn_sub(r, r, d); ++ ++ while (sm2_bn_cmp(r, SM2_P) >= 0) { ++ sm2_bn_sub(r, r, SM2_P); ++ } ++} ++ ++void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a) ++{ ++ sm2_fp_mul(r, a, a); ++} ++ ++void sm2_fp_inv(SM2_Fp r, const SM2_Fp a) ++{ ++ SM2_BN a1; ++ SM2_BN a2; ++ SM2_BN a3; ++ SM2_BN a4; ++ SM2_BN a5; ++ int i; ++ ++ sm2_fp_sqr(a1, a); ++ sm2_fp_mul(a2, a1, a); ++ sm2_fp_sqr(a3, a2); ++ sm2_fp_sqr(a3, a3); ++ sm2_fp_mul(a3, a3, a2); ++ sm2_fp_sqr(a4, a3); ++ sm2_fp_sqr(a4, a4); ++ sm2_fp_sqr(a4, a4); ++ sm2_fp_sqr(a4, a4); ++ sm2_fp_mul(a4, a4, a3); ++ sm2_fp_sqr(a5, a4); ++ for (i = 1; i < 8; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a5, a5, a4); ++ for (i = 0; i < 8; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a5, a5, a4); ++ for (i = 0; i < 4; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a5, a5, a3); ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a5, a5, a2); ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a5, a5, a); ++ sm2_fp_sqr(a4, a5); ++ sm2_fp_mul(a3, a4, a1); ++ sm2_fp_sqr(a5, a4); ++ for (i = 1; i < 31; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a4, a5, a4); ++ sm2_fp_sqr(a4, a4); ++ sm2_fp_mul(a4, a4, a); ++ sm2_fp_mul(a3, a4, a2); ++ for (i = 0; i < 33; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a2, a5, a3); ++ sm2_fp_mul(a3, a2, a3); ++ for (i = 0; i < 32; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a2, a5, a3); ++ sm2_fp_mul(a3, a2, a3); ++ sm2_fp_mul(a4, a2, a4); ++ for (i = 0; i < 32; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a2, a5, a3); ++ sm2_fp_mul(a3, a2, a3); ++ sm2_fp_mul(a4, a2, a4); ++ for (i = 0; i < 32; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a2, a5, a3); ++ sm2_fp_mul(a3, a2, a3); ++ sm2_fp_mul(a4, a2, a4); ++ for (i = 0; i < 32; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(a2, a5, a3); ++ sm2_fp_mul(a3, a2, a3); ++ sm2_fp_mul(a4, a2, a4); ++ for (i = 0; i < 32; i++) ++ sm2_fp_sqr(a5, a5); ++ sm2_fp_mul(r, a4, a5); ++ ++ sm2_bn_clean(a1); ++ sm2_bn_clean(a2); ++ sm2_bn_clean(a3); ++ sm2_bn_clean(a4); ++ sm2_bn_clean(a5); ++} ++ ++void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) ++{ ++ sm2_bn_add(r, a, b); ++ if (sm2_bn_cmp(r, SM2_N) >= 0) { ++ sm2_bn_sub(r, r, SM2_N); ++ } ++} ++ ++void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) ++{ ++ if (sm2_bn_cmp(a, b) >= 0) { ++ sm2_bn_sub(r, a, b); ++ } ++ else { ++ SM2_BN t; ++ sm2_bn_add(t, a, SM2_N); ++ sm2_bn_sub(r, t, b); ++ } ++} ++ ++/* barrett reduction */ ++static int sm2_bn288_cmp(const PRUint64 a[9], const PRUint64 b[9]) ++{ ++ int i; ++ for (i = 8; i >= 0; i--) { ++ if (a[i] > b[i]) ++ return 1; ++ if (a[i] < b[i]) ++ return -1; ++ } ++ return 0; ++} ++ ++static void sm2_bn288_add(PRUint64 r[9], const PRUint64 a[9], const PRUint64 b[9]) ++{ ++ int i; ++ r[0] = a[0] + b[0]; ++ for (i = 1; i < 9; i++) { ++ r[i] = a[i] + b[i] + (r[i - 1] >> 32); ++ } ++ for (i = 0; i < 8; i++) { ++ r[i] &= 0xffffffff; ++ } ++} ++ ++static void sm2_bn288_sub(PRUint64 ret[9], const PRUint64 a[9], const PRUint64 b[9]) ++{ ++ int i; ++ PRUint64 r[9]; ++ ++ r[0] = ((PRUint64)1 << 32) + a[0] - b[0]; ++ for (i = 1; i < 8; i++) { ++ r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); ++ r[i - 1] &= 0xffffffff; ++ } ++ r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; ++ r[i - 1] &= 0xffffffff; ++ ++ for (i = 0; i < 9; i++) { ++ ret[i] = r[i]; ++ } ++} ++ ++void sm2_fn_mul(SM2_BN r, const SM2_BN a, const SM2_BN b) ++{ ++ static const PRUint64 mu[8] = { ++ 0xf15149a0, 0x12ac6361, 0xfa323c01, 0x8dfc2096, ++ 1, 1, 1, 0x100000001, ++ }; // only for N=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123 ++ ++ PRUint64 s[17]; ++ PRUint64 zh[9]; ++ PRUint64 zl[9]; ++ PRUint64 q[9]; ++ PRUint64 w; ++ int i, j; ++ ++ /* z = a * b */ ++ for (i = 0; i < 8; i++) { ++ s[i] = 0; ++ } ++ for (i = 0; i < 8; i++) { ++ w = 0; ++ for (j = 0; j < 8; j++) { ++ w += s[i + j] + a[i] * b[j]; ++ s[i + j] = w & 0xffffffff; ++ w >>= 32; ++ } ++ s[i + 8] = w; ++ } ++ ++ /* zl = z mod (2^32)^9 = z[0..8] zh = z / (2^32)^7 = z[7..15] */ ++ for (i = 0; i < 9; i++) { ++ zl[i] = s[i]; ++ zh[i] = s[7 + i]; ++ } ++ ++ /* q = zh * mu / (2^32)^9 */ ++ for (i = 0; i < 9; i++) { ++ s[i] = 0; ++ } ++ for (i = 0; i < 9; i++) { ++ w = 0; ++ for (j = 0; j < 8; j++) { ++ w += s[i + j] + zh[i] * mu[j]; ++ s[i + j] = w & 0xffffffff; ++ w >>= 32; ++ } ++ s[i + 8] = w; ++ } ++ for (i = 0; i < 8; i++) { ++ q[i] = s[9 + i]; ++ } ++ ++ /* q = q * n mod (2^32)^9 */ ++ for (i = 0; i < 8; i++) { ++ s[i] = 0; ++ } ++ for (i = 0; i < 8; i++) { ++ w = 0; ++ for (j = 0; j < 8; j++) { ++ w += s[i + j] + q[i] * SM2_N[j]; ++ s[i + j] = w & 0xffffffff; ++ w >>= 32; ++ } ++ s[i + 8] = w; ++ } ++ for (i = 0; i < 9; i++) { ++ q[i] = s[i]; ++ } ++ ++ /* r = zl - q (mod (2^32)^9) */ ++ if (sm2_bn288_cmp(zl, q)) { ++ sm2_bn288_sub(zl, zl, q); ++ } ++ else { ++ PRUint64 c[9] = { 0,0,0,0,0,0,0,0,0x100000000 }; ++ sm2_bn288_sub(q, c, q); ++ sm2_bn288_add(zl, q, zl); ++ } ++ ++ for (i = 0; i < 8; i++) { ++ r[i] = zl[i]; ++ } ++ r[7] += zl[8] << 32; ++ ++ /* if r >= p do: r = r - n */ ++ while (sm2_bn_cmp(r, SM2_N) >= 0) { ++ sm2_bn_sub(r, r, SM2_N); ++ } ++} ++ ++void sm2_fn_sqr(SM2_BN r, const SM2_BN a) ++{ ++ sm2_fn_mul(r, a, a); ++} ++ ++void sm2_fn_exp(SM2_BN r, const SM2_BN a, const SM2_BN e) ++{ ++ SM2_BN t; ++ PRUint32 w; ++ int i, j; ++ ++ sm2_bn_set_one(t); ++ for (i = 7; i >= 0; i--) { ++ w = (PRUint32)e[i]; ++ for (j = 0; j < 32; j++) { ++ sm2_fn_sqr(t, t); ++ if (w & 0x80000000) { ++ sm2_fn_mul(t, t, a); ++ } ++ w <<= 1; ++ } ++ } ++ ++ sm2_bn_copy(r, t); ++} ++ ++void sm2_fn_inv(SM2_BN r, const SM2_BN a) ++{ ++ SM2_BN e; ++ sm2_bn_sub(e, SM2_N, SM2_TWO); ++ sm2_fn_exp(r, a, e); ++} ++ ++void sm2_fn_rand(SM2_BN r) ++{ ++ sm2_bn_rand_range(r, SM2_N); ++} ++ ++void sm2_jacobian_point_init(SM2_JACOBIAN_POINT* R) ++{ ++ memset(R, 0, sizeof(SM2_JACOBIAN_POINT)); ++ R->X[0] = 1; ++ R->Y[0] = 1; ++} ++ ++int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT* P) ++{ ++ return sm2_bn_is_zero(P->Z); ++} ++ ++void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT* R, const SM2_BN x, const SM2_BN y) ++{ ++ sm2_bn_copy(R->X, x); ++ sm2_bn_copy(R->Y, y); ++ sm2_bn_set_one(R->Z); ++} ++ ++void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT* P, SM2_BN x, SM2_BN y) ++{ ++ SM2_BN z_inv; ++ ++ if (sm2_bn_is_one(P->Z)) { ++ sm2_bn_copy(x, P->X); ++ sm2_bn_copy(y, P->Y); ++ } ++ else { ++ sm2_fp_inv(z_inv, P->Z); ++ if (y) ++ sm2_fp_mul(y, P->Y, z_inv); ++ sm2_fp_sqr(z_inv, z_inv); ++ sm2_fp_mul(x, P->X, z_inv); ++ if (y) ++ sm2_fp_mul(y, y, z_inv); ++ } ++} ++ ++void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT* R, const SM2_JACOBIAN_POINT* P) ++{ ++ const PRUint64* X1 = P->X; ++ const PRUint64* Y1 = P->Y; ++ const PRUint64* Z1 = P->Z; ++ SM2_BN T1; ++ SM2_BN T2; ++ SM2_BN T3; ++ SM2_BN X3; ++ SM2_BN Y3; ++ SM2_BN Z3; ++ ++ if (sm2_jacobian_point_is_at_infinity(P)) { ++ sm2_jacobian_point_copy(R, P); ++ return; ++ } ++ ++ sm2_fp_sqr(T1, Z1); //T1 = Z1^2 ++ sm2_fp_sub(T2, X1, T1); //T2 = X1 - T1 ++ sm2_fp_add(T1, X1, T1); //T1 = X1 + T1 ++ sm2_fp_mul(T2, T2, T1); //T2 = T2 * T1 ++ sm2_fp_tri(T2, T2); //T2 = 3 * T2 ++ sm2_fp_dbl(Y3, Y1); //Y3 = 2 * Y1 ++ sm2_fp_mul(Z3, Y3, Z1); //Z3 = Y3 * Z1 ++ sm2_fp_sqr(Y3, Y3); //Y3 = Y3^2 ++ sm2_fp_mul(T3, Y3, X1); //T3 = Y3 * X1 ++ sm2_fp_sqr(Y3, Y3); //Y3 = Y3^2 ++ sm2_fp_div2(Y3, Y3); //Y3 = Y3/2 ++ sm2_fp_sqr(X3, T2); //X3 = T2^2 ++ sm2_fp_dbl(T1, T3); //T1 = 2 * T1 ++ sm2_fp_sub(X3, X3, T1); //X3 = X3 - T1 ++ sm2_fp_sub(T1, T3, X3); //T1 = T3 - X3 ++ sm2_fp_mul(T1, T1, T2); //T1 = T1 * T2 ++ sm2_fp_sub(Y3, T1, Y3); //Y3 = T1 - Y3 ++ ++ sm2_bn_copy(R->X, X3); ++ sm2_bn_copy(R->Y, Y3); ++ sm2_bn_copy(R->Z, Z3); ++} ++ ++void sm2_jacobian_point_add(SM2_JACOBIAN_POINT* R, const SM2_JACOBIAN_POINT* P, const SM2_JACOBIAN_POINT* Q) ++{ ++ const PRUint64* X1 = P->X; ++ const PRUint64* Y1 = P->Y; ++ const PRUint64* Z1 = P->Z; ++ const PRUint64* x2 = Q->X; ++ const PRUint64* y2 = Q->Y; ++ SM2_BN T1; ++ SM2_BN T2; ++ SM2_BN T3; ++ SM2_BN T4; ++ SM2_BN X3; ++ SM2_BN Y3; ++ SM2_BN Z3; ++ ++ if (sm2_jacobian_point_is_at_infinity(Q)) { ++ sm2_jacobian_point_copy(R, P); ++ return; ++ } ++ ++ if (sm2_jacobian_point_is_at_infinity(P)) { ++ sm2_jacobian_point_copy(R, Q); ++ return; ++ } ++ ++ assert(sm2_bn_is_one(Q->Z)); ++ ++ sm2_fp_sqr(T1, Z1); ++ sm2_fp_mul(T2, T1, Z1); ++ sm2_fp_mul(T1, T1, x2); ++ sm2_fp_mul(T2, T2, y2); ++ sm2_fp_sub(T1, T1, X1); ++ sm2_fp_sub(T2, T2, Y1); ++ if (sm2_bn_is_zero(T1)) { ++ if (sm2_bn_is_zero(T2)) { ++ SM2_JACOBIAN_POINT _Q, * QQ = &_Q; ++ sm2_jacobian_point_set_xy(QQ, x2, y2); ++ ++ sm2_jacobian_point_dbl(R, QQ); ++ return; ++ } ++ else { ++ sm2_jacobian_point_set_infinity(R); ++ return; ++ } ++ } ++ sm2_fp_mul(Z3, Z1, T1); ++ sm2_fp_sqr(T3, T1); ++ sm2_fp_mul(T4, T3, T1); ++ sm2_fp_mul(T3, T3, X1); ++ sm2_fp_dbl(T1, T3); ++ sm2_fp_sqr(X3, T2); ++ sm2_fp_sub(X3, X3, T1); ++ sm2_fp_sub(X3, X3, T4); ++ sm2_fp_sub(T3, T3, X3); ++ sm2_fp_mul(T3, T3, T2); ++ sm2_fp_mul(T4, T4, Y1); ++ sm2_fp_sub(Y3, T3, T4); ++ ++ sm2_bn_copy(R->X, X3); ++ sm2_bn_copy(R->Y, Y3); ++ sm2_bn_copy(R->Z, Z3); ++} ++ ++void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT* R, const SM2_BN k, const SM2_JACOBIAN_POINT* P) ++{ ++ char bits[257] = { 0 }; ++ SM2_JACOBIAN_POINT _Q, * Q = &_Q; ++ SM2_JACOBIAN_POINT _T, * T = &_T; ++ int i; ++ ++ //point_add need affine, can not use point_add ++ if (!sm2_bn_is_one(P->Z)) { ++ SM2_BN x; ++ SM2_BN y; ++ sm2_jacobian_point_get_xy(P, x, y); ++ sm2_jacobian_point_set_xy(T, x, y); ++ P = T; ++ } ++ ++ sm2_jacobian_point_set_infinity(Q); ++ sm2_bn_to_bits(k, bits); ++ for (i = 0; i < 256; i++) { ++ sm2_jacobian_point_dbl(Q, Q); ++ if (bits[i] == '1') { ++ sm2_jacobian_point_add(Q, Q, P); ++ } ++ } ++ sm2_jacobian_point_copy(R, Q); ++} ++ ++void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT* R, const SM2_BN k) ++{ ++ sm2_jacobian_point_mul(R, k, SM2_G); ++} ++ ++ ++SECStatus ++SM2_SignDigestWithSeed(ECPrivateKey* key, SECItem* signature, ++ const SECItem* digest, const unsigned char* kb, const int kblen) ++{ ++ SECStatus rv = SECFailure; ++ ++ SM2_JACOBIAN_POINT _P, * P = &_P; ++ SM2_BN d; ++ SM2_BN e; ++ SM2_BN k; ++ SM2_BN x; ++ SM2_BN r; ++ SM2_BN s; ++ PRUint8 dgst[32]; ++ PRUint8 private_key[32]; ++ PRUint8 rr[32], ss[32]; ++ ++ memcpy(dgst, digest->data, 32); ++ memcpy(private_key, key->privateValue.data, 32); ++ ++random: ++ sm2_bn_from_bytes(d, private_key); ++ ++ sm2_bn_from_bytes(e, dgst); ++ ++ do { ++ sm2_fn_rand(k); ++ } while (sm2_bn_is_zero(k)); ++ ++ sm2_jacobian_point_mul_generator(P, k); ++ sm2_jacobian_point_get_xy(P, x, NULL); ++ ++ sm2_fn_add(r, e, x); ++ ++ if (sm2_bn_is_zero(r)) { ++ goto random; ++ } ++ sm2_bn_add(x, r, k); ++ if (sm2_bn_cmp(x, SM2_N) == 0) { ++ goto random; ++ } ++ ++ sm2_fn_mul(e, r, d); ++ sm2_fn_sub(k, k, e); ++ sm2_fn_add(e, SM2_ONE, d); ++ sm2_fn_inv(e, e); ++ sm2_fn_mul(s, e, k); ++ ++ sm2_bn_to_bytes(r, rr); ++ sm2_bn_to_bytes(s, ss); ++ memcpy(signature->data, rr, 32); ++ memcpy(signature->data + 32, ss, 32); ++ ++ memset(d, 0, sizeof(d)); ++ memset(e, 0, sizeof(e)); ++ memset(k, 0, sizeof(k)); ++ memset(x, 0, sizeof(x)); ++ ++ rv = SECSuccess; ++ return rv; ++} +\ No newline at end of file +diff --git a/nss/lib/freebl/sm2.h b/nss/lib/freebl/sm2.h +new file mode 100644 +index 0000000..e236dcd +--- /dev/null ++++ b/nss/lib/freebl/sm2.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. ++ * ++ * Licensed under the Apache License, Version 2.0 (the License); you may ++ * not use this file except in compliance with the License. ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ */ ++ ++#ifndef _SM2_H_ ++#define _SM2_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include "seccomon.h" ++#include "blapit.h" ++ ++SECStatus SM2_SignDigestWithSeed(ECPrivateKey* key, SECItem* signature, const SECItem* digest, const unsigned char* kb, const int kblen); ++ ++#endif /* _SM2_H_ */ +\ No newline at end of file +-- +2.33.0 + diff --git a/nss-add-implement-of-SM3-digest-algorithm.patch b/nss-add-implement-of-SM3-digest-algorithm.patch new file mode 100644 index 0000000000000000000000000000000000000000..0422c63e03565c02aad16df560b3c0922d07ce65 --- /dev/null +++ b/nss-add-implement-of-SM3-digest-algorithm.patch @@ -0,0 +1,336 @@ +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 + diff --git a/nss-support-SM2-signature-algorithm.patch b/nss-support-SM2-signature-algorithm.patch new file mode 100644 index 0000000000000000000000000000000000000000..04e7ca5e8bdc3c5735857fff7e1451e66bfedfa8 --- /dev/null +++ b/nss-support-SM2-signature-algorithm.patch @@ -0,0 +1,338 @@ +From 730ed23bef70e1726c7d2b5ea67e5cabf59aa448 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Sun, 16 Oct 2022 05:02:53 +0800 +Subject: [PATCH 4/4] nss support SM2 signature algorithm + + Co-authored-by:godcansee +--- + nss/lib/cryptohi/cryptohi.h | 2 ++ + nss/lib/cryptohi/seckey.c | 3 +++ + nss/lib/cryptohi/secsign.c | 43 +++++++++++++++++++++++++++++++++ + nss/lib/cryptohi/secvfy.c | 5 ++++ + nss/lib/freebl/ec.c | 5 +++- + nss/lib/freebl/ecdecode.c | 5 +++- + nss/lib/freebl/ecl/ecl-curve.h | 33 +++++++++++++++++++++++++ + nss/lib/freebl/ecl/ecl-exp.h | 1 + + nss/lib/freebl/freebl_base.gypi | 1 + + nss/lib/freebl/manifest.mn | 2 ++ + nss/lib/nss/nss.def | 6 +++++ + nss/lib/util/pkcs11t.h | 2 ++ + nss/lib/util/secoid.c | 4 +++ + nss/lib/util/secoidt.h | 2 ++ + 14 files changed, 112 insertions(+), 2 deletions(-) + +diff --git a/nss/lib/cryptohi/cryptohi.h b/nss/lib/cryptohi/cryptohi.h +index 7b66f0b..4f99ef9 100644 +--- a/nss/lib/cryptohi/cryptohi.h ++++ b/nss/lib/cryptohi/cryptohi.h +@@ -420,6 +420,8 @@ extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, + const SECAlgorithmID *algid, SECOidTag *hash, + void *wincx); + ++SECStatus SEC_CreateSM2Digest(unsigned char *z, SECItem *pub); ++ + SEC_END_PROTOS + + #endif /* _CRYPTOHI_H_ */ +diff --git a/nss/lib/cryptohi/seckey.c b/nss/lib/cryptohi/seckey.c +index fa13bc3..4bcd43e 100644 +--- a/nss/lib/cryptohi/seckey.c ++++ b/nss/lib/cryptohi/seckey.c +@@ -520,6 +520,7 @@ seckey_GetKeyType(SECOidTag tag) + keyType = dhKey; + break; + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: ++ case SEC_OID_SM2: + keyType = ecKey; + break; + /* accommodate applications that hand us a signature type when they +@@ -776,6 +777,7 @@ SECKEY_ECParamsToKeySize(const SECItem *encodedParams) + + case SEC_OID_SECG_EC_SECP256K1: + case SEC_OID_ANSIX962_EC_PRIME256V1: ++ case SEC_OID_SM2: + return 256; + + case SEC_OID_ANSIX962_EC_C2PNB272W1: +@@ -924,6 +926,7 @@ SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams) + + case SEC_OID_SECG_EC_SECP256K1: + case SEC_OID_ANSIX962_EC_PRIME256V1: ++ case SEC_OID_SM2: + return 256; + + case SEC_OID_ANSIX962_EC_C2PNB272W1: +diff --git a/nss/lib/cryptohi/secsign.c b/nss/lib/cryptohi/secsign.c +index c46b2b1..65627ae 100644 +--- a/nss/lib/cryptohi/secsign.c ++++ b/nss/lib/cryptohi/secsign.c +@@ -861,3 +861,46 @@ SEC_CreateSignatureAlgorithmParameters(PLArenaPool *arena, + return result; + } + } ++ ++// TODO ++const unsigned char zin_default[] = { ++ 0x00, 0x80, // id length ++ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, ++ 0x35, 0x36, 0x37, 0x38, // default id: 1234567812345678 ++ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, // sm2 a ++ 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, ++ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, ++ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93, // sm2 b ++ 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, ++ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, ++ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7, // sm2 x ++ 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, ++ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, ++ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0 // sm2 y ++}; ++ ++SECStatus SEC_CreateSM2Digest(unsigned char *z, SECItem *pub) ++{ ++ unsigned int len; ++ PK11Context *ctx; ++ ++ if (!z || !pub || pub->len != 65) ++ return SECFailure; ++ ++ ctx = PK11_CreateDigestContext(SEC_OID_SM3); ++ if (!ctx) ++ return SECFailure; ++ ++ if (PK11_DigestBegin(ctx) != SECSuccess || ++ PK11_DigestOp(ctx, zin_default, sizeof(zin_default)) != SECSuccess || ++ PK11_DigestOp(ctx, pub->data + 1, 64) != SECSuccess || ++ PK11_DigestFinal(ctx, z, &len, SM3_LENGTH)) { ++ PK11_DestroyContext(ctx, PR_TRUE); ++ return SECFailure; ++ } ++ ++ PK11_DestroyContext(ctx, PR_TRUE); ++ return SECSuccess; ++} +\ No newline at end of file +diff --git a/nss/lib/cryptohi/secvfy.c b/nss/lib/cryptohi/secvfy.c +index 2540a54..01362df 100644 +--- a/nss/lib/cryptohi/secvfy.c ++++ b/nss/lib/cryptohi/secvfy.c +@@ -257,6 +257,8 @@ sec_GetEncAlgFromSigAlg(SECOidTag sigAlg) + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + return SEC_OID_ANSIX962_EC_PUBLIC_KEY; ++ case SEC_OID_SM2_WITH_SM3: ++ return SEC_OID_SM2; + /* we don't implement MD4 hashes */ + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + default: +@@ -399,6 +401,9 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, + return SECFailure; + } + break; ++ case SEC_OID_SM2_WITH_SM3: ++ *hashalg = SEC_OID_SM3; ++ break; + /* we don't implement MD4 hashes */ + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + default: +diff --git a/nss/lib/freebl/ec.c b/nss/lib/freebl/ec.c +index 73a625a..bf2aea7 100644 +--- a/nss/lib/freebl/ec.c ++++ b/nss/lib/freebl/ec.c +@@ -15,6 +15,7 @@ + #include "mplogic.h" + #include "ec.h" + #include "ecl.h" ++#include "sm2.h" + + static const ECMethod kMethods[] = { + { ECCurve25519, +@@ -907,7 +908,9 @@ ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest) + goto cleanup; + + /* Generate ECDSA signature with the specified k value */ +- rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len); ++ rv = key->ecParams.name == ECCurve_sm2p256v1 ? ++ SM2_SignDigestWithSeed(key, signature, digest, kBytes, len) : ++ ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len); + + cleanup: + if (kBytes) { +diff --git a/nss/lib/freebl/ecdecode.c b/nss/lib/freebl/ecdecode.c +index 652ad42..4c090d2 100644 +--- a/nss/lib/freebl/ecdecode.c ++++ b/nss/lib/freebl/ecdecode.c +@@ -179,7 +179,10 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519, ec_field_plain, + params)); + break; +- ++ case SEC_OID_SM2: ++ /* Populate params for Curve SM2 */ ++ CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_sm2p256v1, ec_field_plain, ++ params)); + default: + break; + }; +diff --git a/nss/lib/freebl/ecl/ecl-curve.h b/nss/lib/freebl/ecl/ecl-curve.h +index fc8003f..e64fe4d 100644 +--- a/nss/lib/freebl/ecl/ecl-curve.h ++++ b/nss/lib/freebl/ecl/ecl-curve.h +@@ -206,6 +206,38 @@ static const ECCurveBytes ecCurve_25519 = { + KU_KEY_AGREEMENT + }; + ++static const PRUint8 sm2_irr[32] = ++ { 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; ++static const PRUint8 sm2_a[32] = ++ { 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc }; ++static const PRUint8 sm2_b[32] = ++ { 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, ++ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, ++ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93 }; ++static const PRUint8 sm2_x[32] = ++ { 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, ++ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, ++ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7 }; ++static const PRUint8 sm2_y[32] = ++ { 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, ++ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, ++ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0 }; ++static const PRUint8 sm2_order[32] = ++ { 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b, ++ 0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23 }; ++ ++static const ECCurveBytes ecCurve_sm2p256v1 = { ++ "sm2p256v1", ECField_GFp, 256, ++ sm2_irr, sm2_a, sm2_b, sm2_x, sm2_y, sm2_order, NULL, ++ 8, 128, 66, 32, // TODO ++ KU_KEY_AGREEMENT ++}; ++ + /* mapping between ECCurveName enum and pointers to ECCurveParams */ + static const ECCurveBytes *ecCurve_map[] = { + NULL, /* ECCurve_noName */ +@@ -267,6 +299,7 @@ static const ECCurveBytes *ecCurve_map[] = { + NULL, /* ECCurve_WTLS_8 */ + NULL, /* ECCurve_WTLS_9 */ + &ecCurve_25519, /* ECCurve25519 */ ++ &ecCurve_sm2p256v1, /* ECCurve_sm2p256v1 */ + NULL /* ECCurve_pastLastCurve */ + }; + +diff --git a/nss/lib/freebl/ecl/ecl-exp.h b/nss/lib/freebl/ecl/ecl-exp.h +index 44adb8a..d071fc9 100644 +--- a/nss/lib/freebl/ecl/ecl-exp.h ++++ b/nss/lib/freebl/ecl/ecl-exp.h +@@ -132,6 +132,7 @@ typedef enum { + /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */ + + ECCurve25519, ++ ECCurve_sm2p256v1, + + ECCurve_pastLastCurve + } ECCurveName; +diff --git a/nss/lib/freebl/freebl_base.gypi b/nss/lib/freebl/freebl_base.gypi +index 85a569f..253ce8d 100644 +--- a/nss/lib/freebl/freebl_base.gypi ++++ b/nss/lib/freebl/freebl_base.gypi +@@ -59,6 +59,7 @@ + 'sha_fast.c', + 'shvfy.c', + 'sm3.c', ++ 'sm2.c', + 'sysrand.c', + 'tlsprfalg.c', + ], +diff --git a/nss/lib/freebl/manifest.mn b/nss/lib/freebl/manifest.mn +index fd3218d..2dbf7c9 100644 +--- a/nss/lib/freebl/manifest.mn ++++ b/nss/lib/freebl/manifest.mn +@@ -158,6 +158,7 @@ CSRCS = \ + $(LOWHASH_SRCS) \ + $(EXTRA_SRCS) \ + sm3.c \ ++ sm2.c \ + $(NULL) + + ifndef NSS_DISABLE_DEPRECATED_SEED +@@ -188,6 +189,7 @@ ALL_HDRS = \ + vis_proto.h \ + seed.h \ + sm3.h \ ++ sm2.h \ + $(NULL) + + +diff --git a/nss/lib/nss/nss.def b/nss/lib/nss/nss.def +index e87395b..2bc4965 100644 +--- a/nss/lib/nss/nss.def ++++ b/nss/lib/nss/nss.def +@@ -1238,3 +1238,9 @@ PK11_SlotGetLastFIPSStatus; + ;+ local: + ;+ *; + ;+}; ++;+NSS_openEuler { ++;+ global: ++SEC_CreateSM2Digest; ++;+ local: ++;+ *; ++;+}; +diff --git a/nss/lib/util/pkcs11t.h b/nss/lib/util/pkcs11t.h +index 93cb8d1..a1e3323 100644 +--- a/nss/lib/util/pkcs11t.h ++++ b/nss/lib/util/pkcs11t.h +@@ -1243,6 +1243,8 @@ typedef CK_ULONG CK_MECHANISM_TYPE; + + /* new for TODO */ + #define CKM_SM3 0x0000402eUL ++#define CKM_SM2 0x0000402fUL ++#define CKM_SM2_WITH_SM3 0x00004030UL + + #define CKM_VENDOR_DEFINED 0x80000000UL + +diff --git a/nss/lib/util/secoid.c b/nss/lib/util/secoid.c +index fd620e9..d68f1b6 100644 +--- a/nss/lib/util/secoid.c ++++ b/nss/lib/util/secoid.c +@@ -606,6 +606,8 @@ CONST_OID curve25519[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01 + * 1.2.156.197.1.401 + */ + CONST_OID sm3[] = { 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x11 }; ++CONST_OID sm2[] = { 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D }; ++CONST_OID sm2_with_sm3[] = { 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 }; + + #define OI(x) \ + { \ +@@ -1801,6 +1803,8 @@ const static SECOidData oids[SEC_OID_TOTAL] = { + "IPsec User", + CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION), + OD(sm3, SEC_OID_SM3, "SM3", CKM_SM3, INVALID_CERT_EXTENSION), ++ OD(sm2, SEC_OID_SM2, "SM2", CKM_SM2, INVALID_CERT_EXTENSION), ++ OD(sm2_with_sm3, SEC_OID_SM2_WITH_SM3, "SM2_WITH_SM3", CKM_SM2_WITH_SM3, INVALID_CERT_EXTENSION), + }; + + /* PRIVATE EXTENDED SECOID Table +diff --git a/nss/lib/util/secoidt.h b/nss/lib/util/secoidt.h +index 984b7fb..fe49661 100644 +--- a/nss/lib/util/secoidt.h ++++ b/nss/lib/util/secoidt.h +@@ -503,6 +503,8 @@ typedef enum { + SEC_OID_EXT_KEY_USAGE_IPSEC_USER = 363, + + SEC_OID_SM3 = 364, ++ SEC_OID_SM2 = 365, ++ SEC_OID_SM2_WITH_SM3 = 366, + + SEC_OID_TOTAL + } SECOidTag; +-- +2.33.0 + diff --git a/nss-support-SM3-digest-algorithm.patch b/nss-support-SM3-digest-algorithm.patch new file mode 100644 index 0000000000000000000000000000000000000000..0702fd8efa4a7ebfd303f73264787f4dcf58ca06 --- /dev/null +++ b/nss-support-SM3-digest-algorithm.patch @@ -0,0 +1,560 @@ +From 497ba4cd0fdb2ba1bd6f2fcf8a9d0ec02373fc82 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Sun, 16 Oct 2022 05:01:37 +0800 +Subject: [PATCH 3/4] nss support SM3 digest algorithm + +Co-authored-by:godcansee +--- + nss/lib/cryptohi/sechash.c | 19 +++++++ + nss/lib/freebl/blapi.h | 18 +++++++ + nss/lib/freebl/blapit.h | 4 ++ + nss/lib/freebl/freebl_base.gypi | 1 + + nss/lib/freebl/ldvector.c | 13 ++++- + nss/lib/freebl/loader.c | 90 +++++++++++++++++++++++++++++++++ + nss/lib/freebl/loader.h | 14 +++++ + nss/lib/freebl/manifest.mn | 2 + + nss/lib/freebl/rawhash.c | 12 +++++ + nss/lib/pk11wrap/pk11pars.c | 2 + + nss/lib/pk11wrap/pk11slot.c | 11 +++- + nss/lib/pk11wrap/secmod.h | 1 + + nss/lib/softoken/pkcs11.c | 1 + + nss/lib/softoken/pkcs11c.c | 1 + + nss/lib/util/hasht.h | 2 + + nss/lib/util/pkcs11t.h | 3 ++ + nss/lib/util/secoid.c | 6 +++ + nss/lib/util/secoidt.h | 2 + + nss/lib/util/utilmodt.h | 1 + + nss/lib/util/utilpars.c | 1 + + nss/lib/util/utilparst.h | 2 +- + 21 files changed, 202 insertions(+), 4 deletions(-) + +diff --git a/nss/lib/cryptohi/sechash.c b/nss/lib/cryptohi/sechash.c +index 474fdff..7c4cdbf 100644 +--- a/nss/lib/cryptohi/sechash.c ++++ b/nss/lib/cryptohi/sechash.c +@@ -85,6 +85,12 @@ sha512_NewContext(void) + return (void *)PK11_CreateDigestContext(SEC_OID_SHA512); + } + ++static void * ++sm3_NewContext(void) ++{ ++ return (void *)PK11_CreateDigestContext(SEC_OID_SM3); ++} ++ + const SECHashObject SECHashObjects[] = { + { 0, + (void *(*)(void))null_hash_new_context, +@@ -166,6 +172,16 @@ const SECHashObject SECHashObjects[] = { + PK11_DigestFinal, + SHA224_BLOCK_LENGTH, + HASH_AlgSHA224 }, ++ { SM3_LENGTH, ++ (void *(*)(void))sm3_NewContext, ++ (void *(*)(void *))PK11_CloneContext, ++ (void (*)(void *, PRBool))PK11_DestroyContext, ++ (void (*)(void *))PK11_DigestBegin, ++ (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp, ++ (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) ++ PK11_DigestFinal, ++ SM3_BLOCK_LENGTH, ++ HASH_AlgSM3 }, + }; + + const SECHashObject * +@@ -201,6 +217,9 @@ HASH_GetHashTypeByOidTag(SECOidTag hashOid) + case SEC_OID_SHA512: + ht = HASH_AlgSHA512; + break; ++ case SEC_OID_SM3: ++ ht = HASH_AlgSM3; ++ break; + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + break; +diff --git a/nss/lib/freebl/blapi.h b/nss/lib/freebl/blapi.h +index 94fd802..d53c196 100644 +--- a/nss/lib/freebl/blapi.h ++++ b/nss/lib/freebl/blapi.h +@@ -1484,6 +1484,24 @@ extern SECStatus SHA384_Flatten(SHA384Context *cx, unsigned char *space); + extern SHA384Context *SHA384_Resurrect(unsigned char *space, void *arg); + extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src); + ++/******************************************/ ++ ++extern SM3Context *SM3_NewContext(void); ++extern void SM3_DestroyContext(SM3Context *cx, PRBool freeit); ++extern void SM3_Begin(SM3Context *cx); ++extern void SM3_Update(SM3Context *cx, const unsigned char *input, ++ unsigned int inputLen); ++extern void SM3_End(SM3Context *cx, unsigned char *digest, ++ unsigned int *digestLen, unsigned int maxDigestLen); ++extern SECStatus SM3_HashBuf(unsigned char *dest, const unsigned char *src, ++ PRUint32 src_length); ++extern SECStatus SM3_Hash(unsigned char *dest, const char *src); ++extern void SM3_TraceState(SM3Context *cx); ++extern unsigned int SM3_FlattenSize(SM3Context *cx); ++extern SECStatus SM3_Flatten(SM3Context *cx, unsigned char *space); ++extern SM3Context *SM3_Resurrect(unsigned char *space, void *arg); ++extern void SM3_Clone(SM3Context *dest, SM3Context *src); ++ + /**************************************** + * implement TLS 1.0 Pseudo Random Function (PRF) and TLS P_hash function + */ +diff --git a/nss/lib/freebl/blapit.h b/nss/lib/freebl/blapit.h +index 0054e17..2d400ec 100644 +--- a/nss/lib/freebl/blapit.h ++++ b/nss/lib/freebl/blapit.h +@@ -98,6 +98,7 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated)); + #define SHA384_LENGTH 48 /* bytes */ + #define SHA512_LENGTH 64 /* bytes */ + #define BLAKE2B512_LENGTH 64 /* Bytes */ ++#define SM3_LENGTH 32 /* bytes */ + #define HASH_LENGTH_MAX SHA512_LENGTH + + /* +@@ -112,6 +113,7 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated)); + #define SHA384_BLOCK_LENGTH 128 /* bytes */ + #define SHA512_BLOCK_LENGTH 128 /* bytes */ + #define BLAKE2B_BLOCK_LENGTH 128 /* Bytes */ ++#define SM3_BLOCK_LENGTH 64 /* bytes */ + #define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH + + #define AES_BLOCK_SIZE 16 /* bytes */ +@@ -243,6 +245,7 @@ struct MD5ContextStr; + struct SHA1ContextStr; + struct SHA256ContextStr; + struct SHA512ContextStr; ++struct SM3ContextStr; + struct AESKeyWrapContextStr; + struct SEEDContextStr; + struct ChaCha20ContextStr; +@@ -264,6 +267,7 @@ typedef struct SHA256ContextStr SHA224Context; + typedef struct SHA512ContextStr SHA512Context; + /* SHA384Context is really a SHA512ContextStr. This is not a mistake. */ + typedef struct SHA512ContextStr SHA384Context; ++typedef struct SM3ContextStr SM3Context; + typedef struct AESKeyWrapContextStr AESKeyWrapContext; + typedef struct SEEDContextStr SEEDContext; + typedef struct ChaCha20ContextStr ChaCha20Context; +diff --git a/nss/lib/freebl/freebl_base.gypi b/nss/lib/freebl/freebl_base.gypi +index afbffac..85a569f 100644 +--- a/nss/lib/freebl/freebl_base.gypi ++++ b/nss/lib/freebl/freebl_base.gypi +@@ -58,6 +58,7 @@ + 'rsapkcs.c', + 'sha_fast.c', + 'shvfy.c', ++ 'sm3.c', + 'sysrand.c', + 'tlsprfalg.c', + ], +diff --git a/nss/lib/freebl/ldvector.c b/nss/lib/freebl/ldvector.c +index ac3b862..67bb001 100644 +--- a/nss/lib/freebl/ldvector.c ++++ b/nss/lib/freebl/ldvector.c +@@ -376,9 +376,20 @@ static const struct FREEBLVectorStr vector = + /* End of version 3.024 */ + ChaCha20_InitContext, + ChaCha20_CreateContext, +- ChaCha20_DestroyContext ++ ChaCha20_DestroyContext, + + /* End of version 3.025 */ ++ SM3_NewContext, ++ SM3_DestroyContext, ++ SM3_Begin, ++ SM3_Update, ++ SM3_End, ++ SM3_HashBuf, ++ SM3_Hash, ++ SM3_TraceState, ++ SM3_FlattenSize, ++ SM3_Flatten, ++ SM3_Resurrect + }; + + const FREEBLVector* +diff --git a/nss/lib/freebl/loader.c b/nss/lib/freebl/loader.c +index 692a883..47e4cca 100644 +--- a/nss/lib/freebl/loader.c ++++ b/nss/lib/freebl/loader.c +@@ -2446,3 +2446,93 @@ CMAC_Destroy(CMACContext *ctx, PRBool free_it) + return; + (vector->p_CMAC_Destroy)(ctx, free_it); + } ++ ++SECStatus ++SM3_Hash(unsigned char *dest, const char *src) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return SECFailure; ++ return (vector->p_SM3_Hash)(dest, src); ++} ++ ++SECStatus ++SM3_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return SECFailure; ++ return (vector->p_SM3_HashBuf)(dest, src, src_length); ++} ++ ++SM3Context * ++SM3_NewContext(void) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return NULL; ++ return (vector->p_SM3_NewContext)(); ++} ++ ++void ++SM3_DestroyContext(SM3Context *cx, PRBool freeit) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return; ++ (vector->p_SM3_DestroyContext)(cx, freeit); ++} ++ ++void ++SM3_Begin(SM3Context *cx) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return; ++ (vector->p_SM3_Begin)(cx); ++} ++ ++void ++SM3_Update(SM3Context *cx, const unsigned char *input, ++ unsigned int inputLen) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return; ++ (vector->p_SM3_Update)(cx, input, inputLen); ++} ++ ++void ++SM3_End(SM3Context *cx, unsigned char *digest, ++ unsigned int *digestLen, unsigned int maxDigestLen) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return; ++ (vector->p_SM3_End)(cx, digest, digestLen, maxDigestLen); ++} ++ ++void ++SM3_TraceState(SM3Context *cx) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return; ++ (vector->p_SM3_TraceState)(cx); ++} ++ ++unsigned int ++SM3_FlattenSize(SM3Context *cx) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return 0; ++ return (vector->p_SM3_FlattenSize)(cx); ++} ++ ++SECStatus ++SM3_Flatten(SM3Context *cx, unsigned char *space) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return SECFailure; ++ return (vector->p_SM3_Flatten)(cx, space); ++} ++ ++SM3Context * ++SM3_Resurrect(unsigned char *space, void *arg) ++{ ++ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) ++ return NULL; ++ return (vector->p_SM3_Resurrect)(space, arg); ++} +diff --git a/nss/lib/freebl/loader.h b/nss/lib/freebl/loader.h +index eb3046d..f67595e 100644 +--- a/nss/lib/freebl/loader.h ++++ b/nss/lib/freebl/loader.h +@@ -831,6 +831,20 @@ struct FREEBLVectorStr { + void (*p_ChaCha20_DestroyContext)(ChaCha20Context *ctx, PRBool freeit); + + /* Version 3.025 came to here */ ++ SM3Context *(*p_SM3_NewContext)(void); ++ void (*p_SM3_DestroyContext)(SM3Context *cx, PRBool freeit); ++ void (*p_SM3_Begin)(SM3Context *cx); ++ void (*p_SM3_Update)(SM3Context *cx, const unsigned char *input, ++ unsigned int inputLen); ++ void (*p_SM3_End)(SM3Context *cx, unsigned char *digest, ++ unsigned int *digestLen, unsigned int maxDigestLen); ++ SECStatus (*p_SM3_HashBuf)(unsigned char *dest, const unsigned char *src, ++ PRUint32 src_length); ++ SECStatus (*p_SM3_Hash)(unsigned char *dest, const char *src); ++ void (*p_SM3_TraceState)(SM3Context *cx); ++ unsigned int (*p_SM3_FlattenSize)(SM3Context *cx); ++ SECStatus (*p_SM3_Flatten)(SM3Context *cx, unsigned char *space); ++ SM3Context *(*p_SM3_Resurrect)(unsigned char *space, void *arg); + + /* Add new function pointers at the end of this struct and bump + * FREEBL_VERSION at the beginning of this file. */ +diff --git a/nss/lib/freebl/manifest.mn b/nss/lib/freebl/manifest.mn +index 9dac210..fd3218d 100644 +--- a/nss/lib/freebl/manifest.mn ++++ b/nss/lib/freebl/manifest.mn +@@ -157,6 +157,7 @@ CSRCS = \ + $(STUBS_SRCS) \ + $(LOWHASH_SRCS) \ + $(EXTRA_SRCS) \ ++ sm3.c \ + $(NULL) + + ifndef NSS_DISABLE_DEPRECATED_SEED +@@ -186,6 +187,7 @@ ALL_HDRS = \ + shsign.h \ + vis_proto.h \ + seed.h \ ++ sm3.h \ + $(NULL) + + +diff --git a/nss/lib/freebl/rawhash.c b/nss/lib/freebl/rawhash.c +index 551727b..c74cbbc 100644 +--- a/nss/lib/freebl/rawhash.c ++++ b/nss/lib/freebl/rawhash.c +@@ -141,6 +141,18 @@ const SECHashObject SECRawHashObjects[] = { + HASH_AlgSHA224, + (void (*)(void *, unsigned char *, unsigned int *, + unsigned int))SHA224_EndRaw }, ++ { SM3_LENGTH, ++ (void *(*)(void))SM3_NewContext, ++ (void *(*)(void *))null_hash_clone_context, ++ (void (*)(void *, PRBool))SM3_DestroyContext, ++ (void (*)(void *))SM3_Begin, ++ (void (*)(void *, const unsigned char *, unsigned int))SM3_Update, ++ (void (*)(void *, unsigned char *, unsigned int *, ++ unsigned int))SM3_End, ++ SM3_BLOCK_LENGTH, ++ HASH_AlgSM3, ++ NULL /* end_raw */ ++ }, + }; + + const SECHashObject * +diff --git a/nss/lib/pk11wrap/pk11pars.c b/nss/lib/pk11wrap/pk11pars.c +index 23e5af3..c127309 100644 +--- a/nss/lib/pk11wrap/pk11pars.c ++++ b/nss/lib/pk11wrap/pk11pars.c +@@ -338,6 +338,8 @@ static const oidValDef hashOptList[] = { + { CIPHER_NAME("SHA384"), SEC_OID_SHA384, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, + { CIPHER_NAME("SHA512"), SEC_OID_SHA512, ++ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }, ++ { CIPHER_NAME("SM3"), SEC_OID_SM3, + NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE } + }; + +diff --git a/nss/lib/pk11wrap/pk11slot.c b/nss/lib/pk11wrap/pk11slot.c +index c320019..26916b2 100644 +--- a/nss/lib/pk11wrap/pk11slot.c ++++ b/nss/lib/pk11wrap/pk11slot.c +@@ -51,6 +51,7 @@ const PK11DefaultArrayEntry PK11_DefaultArray[] = { + { "SHA512", SECMOD_SHA512_FLAG, CKM_SHA512 }, + { "MD5", SECMOD_MD5_FLAG, CKM_MD5 }, + { "MD2", SECMOD_MD2_FLAG, CKM_MD2 }, ++ { "SM3", SECMOD_SM3_FLAG, CKM_SM3 }, + { "SSL", SECMOD_SSL_FLAG, CKM_SSL3_PRE_MASTER_KEY_GEN }, + { "TLS", SECMOD_TLS_FLAG, CKM_TLS_MASTER_KEY_DERIVE }, + { "SKIPJACK", SECMOD_FORTEZZA_FLAG, CKM_SKIPJACK_CBC64 }, +@@ -93,7 +94,8 @@ static PK11SlotList + pk11_tlsSlotList, + pk11_randomSlotList, + pk11_sha256SlotList, +- pk11_sha512SlotList; /* slots do SHA512 and SHA384 */ ++ pk11_sha512SlotList, /* slots do SHA512 and SHA384 */ ++ pk11_sm3SlotList; + + /************************************************************ + * Generic Slot List and Slot List element manipulations +@@ -838,6 +840,7 @@ PK11_InitSlotLists(void) + pk11_InitSlotListStatic(&pk11_randomSlotList); + pk11_InitSlotListStatic(&pk11_sha256SlotList); + pk11_InitSlotListStatic(&pk11_sha512SlotList); ++ pk11_InitSlotListStatic(&pk11_sm3SlotList); + return SECSuccess; + } + +@@ -864,6 +867,7 @@ PK11_DestroySlotLists(void) + pk11_FreeSlotListStatic(&pk11_randomSlotList); + pk11_FreeSlotListStatic(&pk11_sha256SlotList); + pk11_FreeSlotListStatic(&pk11_sha512SlotList); ++ pk11_FreeSlotListStatic(&pk11_sm3SlotList); + return; + } + +@@ -911,6 +915,8 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type) + return &pk11_md5SlotList; + case CKM_MD2: + return &pk11_md2SlotList; ++ case CKM_SM3: ++ return &pk11_sm3SlotList; + case CKM_RC2_ECB: + case CKM_RC2_CBC: + return &pk11_rc2SlotList; +@@ -2362,7 +2368,8 @@ PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type, + (type[i] != CKM_SHA384) && + (type[i] != CKM_SHA512) && + (type[i] != CKM_MD5) && +- (type[i] != CKM_MD2)) { ++ (type[i] != CKM_MD2) && ++ (type[i] != CKM_SM3)) { + listNeedLogin = PR_TRUE; + break; + } +diff --git a/nss/lib/pk11wrap/secmod.h b/nss/lib/pk11wrap/secmod.h +index fcc7707..dbc58e8 100644 +--- a/nss/lib/pk11wrap/secmod.h ++++ b/nss/lib/pk11wrap/secmod.h +@@ -29,6 +29,7 @@ + #define PUBLIC_MECH_CAMELLIA_FLAG 0x00010000ul + #define PUBLIC_MECH_SEED_FLAG 0x00020000ul + #define PUBLIC_MECH_ECC_FLAG 0x00040000ul ++#define PUBLIC_MECH_SM3_FLAG 0x00080000ul + + #define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul + #define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul +diff --git a/nss/lib/softoken/pkcs11.c b/nss/lib/softoken/pkcs11.c +index 3f49333..e0b3e2e 100644 +--- a/nss/lib/softoken/pkcs11.c ++++ b/nss/lib/softoken/pkcs11.c +@@ -452,6 +452,7 @@ static const struct mechanismList mechanisms[] = { + { CKM_NSS_TLS_PRF_GENERAL_SHA256, + { 0, 512, CKF_SN_VR }, + PR_FALSE }, ++ { CKM_SM3, { 0, 0, CKF_DIGEST }, PR_FALSE }, + /* ------------------------- HKDF Operations -------------------------- */ + { CKM_HKDF_DERIVE, { 1, 255 * 64, CKF_DERIVE }, PR_TRUE }, + { CKM_HKDF_DATA, { 1, 255 * 64, CKF_DERIVE }, PR_TRUE }, +diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c +index 201a0c7..c6f1e0a 100644 +--- a/nss/lib/softoken/pkcs11c.c ++++ b/nss/lib/softoken/pkcs11c.c +@@ -1939,6 +1939,7 @@ NSC_DigestInit(CK_SESSION_HANDLE hSession, + INIT_MECH(SHA256) + INIT_MECH(SHA384) + INIT_MECH(SHA512) ++ INIT_MECH(SM3) + + default: + crv = CKR_MECHANISM_INVALID; +diff --git a/nss/lib/util/hasht.h b/nss/lib/util/hasht.h +index 536d34c..556c6ba 100644 +--- a/nss/lib/util/hasht.h ++++ b/nss/lib/util/hasht.h +@@ -24,6 +24,7 @@ typedef enum { + HASH_AlgSHA384 = 5, + HASH_AlgSHA512 = 6, + HASH_AlgSHA224 = 7, ++ HASH_AlgSM3 = 8, + HASH_AlgTOTAL + } HASH_HashType; + +@@ -37,6 +38,7 @@ typedef enum { + #define SHA256_LENGTH 32 + #define SHA384_LENGTH 48 + #define SHA512_LENGTH 64 ++#define SM3_LENGTH 32 + #define HASH_LENGTH_MAX SHA512_LENGTH + + /* +diff --git a/nss/lib/util/pkcs11t.h b/nss/lib/util/pkcs11t.h +index 2e3218e..93cb8d1 100644 +--- a/nss/lib/util/pkcs11t.h ++++ b/nss/lib/util/pkcs11t.h +@@ -1241,6 +1241,9 @@ typedef CK_ULONG CK_MECHANISM_TYPE; + #define CKM_HKDF_KEY_GEN 0x0000402cUL + #define CKM_SALSA20_KEY_GEN 0x0000402dUL + ++/* new for TODO */ ++#define CKM_SM3 0x0000402eUL ++ + #define CKM_VENDOR_DEFINED 0x80000000UL + + typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; +diff --git a/nss/lib/util/secoid.c b/nss/lib/util/secoid.c +index b10f859..fd620e9 100644 +--- a/nss/lib/util/secoid.c ++++ b/nss/lib/util/secoid.c +@@ -602,6 +602,11 @@ CONST_OID evIncorporationCountry[] = { EV_NAME_ATTRIBUTE, 3 }; + */ + CONST_OID curve25519[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01 }; + ++/* https://datatracker.ietf.org/doc/html/draft-oscca-cfrg-sm3-02 ++ * 1.2.156.197.1.401 ++ */ ++CONST_OID sm3[] = { 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x11 }; ++ + #define OI(x) \ + { \ + siDEROID, (unsigned char *)x, sizeof x \ +@@ -1795,6 +1800,7 @@ const static SECOidData oids[SEC_OID_TOTAL] = { + SEC_OID_EXT_KEY_USAGE_IPSEC_USER, + "IPsec User", + CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION), ++ OD(sm3, SEC_OID_SM3, "SM3", CKM_SM3, INVALID_CERT_EXTENSION), + }; + + /* PRIVATE EXTENDED SECOID Table +diff --git a/nss/lib/util/secoidt.h b/nss/lib/util/secoidt.h +index 2b7eb21..984b7fb 100644 +--- a/nss/lib/util/secoidt.h ++++ b/nss/lib/util/secoidt.h +@@ -502,6 +502,8 @@ typedef enum { + SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL = 362, + SEC_OID_EXT_KEY_USAGE_IPSEC_USER = 363, + ++ SEC_OID_SM3 = 364, ++ + SEC_OID_TOTAL + } SECOidTag; + +diff --git a/nss/lib/util/utilmodt.h b/nss/lib/util/utilmodt.h +index e1555f3..cc927dd 100644 +--- a/nss/lib/util/utilmodt.h ++++ b/nss/lib/util/utilmodt.h +@@ -28,6 +28,7 @@ + #define SECMOD_CAMELLIA_FLAG 0x00010000L /* = PUBLIC_MECH_CAMELLIA_FLAG */ + #define SECMOD_SEED_FLAG 0x00020000L + #define SECMOD_ECC_FLAG 0x00040000L ++#define SECMOD_SM3_FLAG 0x00080000L + /* reserved bit for future, do not use */ + #define SECMOD_RESERVED_FLAG 0X08000000L + #define SECMOD_FRIENDLY_FLAG 0x10000000L +diff --git a/nss/lib/util/utilpars.c b/nss/lib/util/utilpars.c +index c248aa6..56ede24 100644 +--- a/nss/lib/util/utilpars.c ++++ b/nss/lib/util/utilpars.c +@@ -607,6 +607,7 @@ static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = { + NSSUTIL_ARG_ENTRY(AES, SECMOD_AES_FLAG), + NSSUTIL_ARG_ENTRY(Camellia, SECMOD_CAMELLIA_FLAG), + NSSUTIL_ARG_ENTRY(SEED, SECMOD_SEED_FLAG), ++ NSSUTIL_ARG_ENTRY(SM3, SECMOD_SM3_FLAG), + NSSUTIL_ARG_ENTRY(PublicCerts, SECMOD_FRIENDLY_FLAG), + NSSUTIL_ARG_ENTRY(RANDOM, SECMOD_RANDOM_FLAG), + NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG), +diff --git a/nss/lib/util/utilparst.h b/nss/lib/util/utilparst.h +index 5dda090..7a4c9f7 100644 +--- a/nss/lib/util/utilparst.h ++++ b/nss/lib/util/utilparst.h +@@ -43,7 +43,7 @@ + #define NSSUTIL_DEFAULT_INTERNAL_INIT3 \ + " askpw=any timeout=30})\"" + #define NSSUTIL_DEFAULT_SFTKN_FLAGS \ +- "slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]" ++ "slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512,SM3]" + + #define NSSUTIL_DEFAULT_CIPHER_ORDER 0 + #define NSSUTIL_DEFAULT_TRUST_ORDER 50 +-- +2.33.0 + diff --git a/nss.spec b/nss.spec index a6280702e7bad15aaabb74bedde2617ccde48f20..ea3de34a4bc5311399f8c2412bb64c55d3b9a84d 100644 --- a/nss.spec +++ b/nss.spec @@ -14,7 +14,7 @@ Summary: Network Security Services Name: nss Version: %{nss_version} -Release: 3 +Release: 4 License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Provides: nss-system-init @@ -43,6 +43,12 @@ Patch0: nss-539183.patch Patch6000: backport-CVE-2021-43527.patch +# Feature: support sm2 and sm3 +Patch9000: nss-add-implement-of-SM3-digest-algorithm.patch +Patch9001: nss-add-implement-of-SM2-signature-algorithm.patch +Patch9002: nss-support-SM3-digest-algorithm.patch +Patch9003: nss-support-SM2-signature-algorithm.patch + %description Network Security Services (NSS) is a set of libraries designed to support cross-platform development of security-enabled client and @@ -129,6 +135,11 @@ pushd nss %patch6000 -p1 popd +%patch9000 -p1 +%patch9001 -p1 +%patch9002 -p1 +%patch9003 -p1 + %build export NSS_FORCE_FIPS=1 @@ -549,6 +560,9 @@ update-crypto-policies &>/dev/null||: %doc %{_mandir}/man* %changelog +* Mon Oct 10 2022 godcansee - 3.72-4 +- add feature to support for sm2,sm3 + * Sat Jul 30 2022 zhangjun - 3.72-3 - remove Requires nss-help