代码拉取完成,页面将自动刷新
diff -Naur libxcrypt-4.4.28.orig/Makefile.am libxcrypt-4.4.28/Makefile.am
--- libxcrypt-4.4.28.orig/Makefile.am 2023-03-06 15:05:34.353791338 +0800
+++ libxcrypt-4.4.28/Makefile.am 2023-03-06 15:05:51.600787580 +0800
@@ -5,7 +5,7 @@
#
AUTOMAKE_OPTIONS = \
- 1.14 \
+ 1.16 \
dist-bzip2 \
dist-xz \
filename-length-max=99 \
@@ -80,6 +80,7 @@
lib/alg-sha1.h \
lib/alg-sha256.h \
lib/alg-sha512.h \
+ lib/alg-sm3.h \
lib/alg-yescrypt.h \
lib/byteorder.h \
lib/crypt-obsolete.h \
@@ -108,6 +109,7 @@
lib/alg-sha1.c \
lib/alg-sha256.c \
lib/alg-sha512.c \
+ lib/alg-sm3.c \
lib/alg-yescrypt-common.c \
lib/alg-yescrypt-opt.c \
lib/crypt-bcrypt.c \
@@ -119,6 +121,7 @@
lib/crypt-pbkdf1-sha1.c \
lib/crypt-scrypt.c \
lib/crypt-sha256.c \
+ lib/crypt-sm3.c \
lib/crypt-sha512.c \
lib/crypt-static.c \
lib/crypt-sunmd5.c \
@@ -363,6 +366,7 @@
test/alg-sha1 \
test/alg-sha256 \
test/alg-sha512 \
+ test/alg-sm3 \
test/alg-yescrypt \
test/badsalt \
test/badsetting \
@@ -556,6 +560,10 @@
lib/libcrypt_la-alg-sha512.lo \
lib/libcrypt_la-util-xbzero.lo \
$(COMMON_TEST_OBJECTS)
+test_alg_sm3_LDADD = \
+ lib/libcrypt_la-alg-sm3.lo \
+ lib/libcrypt_la-util-xbzero.lo \
+ $(COMMON_TEST_OBJECTS)
test_alg_yescrypt_LDADD = \
lib/libcrypt_la-alg-sha256.lo \
lib/libcrypt_la-alg-yescrypt-common.lo \
diff -Naur libxcrypt-4.4.28.orig/doc/crypt.5 libxcrypt-4.4.28/doc/crypt.5
--- libxcrypt-4.4.28.orig/doc/crypt.5 2023-03-06 15:05:34.355791337 +0800
+++ libxcrypt-4.4.28/doc/crypt.5 2023-03-06 17:30:35.703474930 +0800
@@ -234,6 +234,14 @@
but MD5 is so cheap on modern hardware
that it should not be used for new hashes.
.hash "$md5" "\e$md5(,rounds=[1-9][0-9]+)?\e$[./0-9A-Za-z]{8}\e${1,2}[./0-9A-Za-z]{22}" unlimited 8 128 128 48 "4096 to 4,294,963,199"
+.Ss sm3crypt
+A hash based on SM3 with 256-bit output,
+originally developed by China.
+Supported on Linux but not common elsewhere.
+Acceptable for new hashes.
+The default CPU time cost parameter is 5000,
+which is too low for modern hardware.
+.hash "$sm3$" "\e$sm3\e$(rounds=[1-9][0-9]+\e$)?[./0-9A-Za-z]{1,16}\e$[./0-9A-Za-z]{43}" unlimited 8 256 256 "6 to 96" "1000 to 999,999,999"
.Ss md5crypt
A hash based on the MD5 algorithm, originally developed by
Poul-Henning Kamp for FreeBSD.
diff -Naur libxcrypt-4.4.28.orig/lib/alg-sm3.c libxcrypt-4.4.28/lib/alg-sm3.c
--- libxcrypt-4.4.28.orig/lib/alg-sm3.c 1970-01-01 08:00:00.000000000 +0800
+++ libxcrypt-4.4.28/lib/alg-sm3.c 2023-03-06 15:05:51.601787579 +0800
@@ -0,0 +1,375 @@
+#include "crypt-port.h"
+
+#if INCLUDE_sm3crypt
+
+#include "alg-sm3.h"
+#include "byteorder.h"
+
+/* Test vectors:
+
+ "abc"
+ SM3: 66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0
+
+ "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
+ SM3: debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732
+
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ SM3: 639b6cc5 e64d9e37 a390b192 df4fa1ea 0720ab74 7ff692b9 f38c4e66 ad7b8c05
+
+ "a" one million times
+ SM3: c8aaf894 29554029 e231941a 2acc0ad6 1ff2a5ac d8fadd25 847a3a73 2b3b02c3
+
+*/
+
+
+#define ROTR(x, n) ((x << n) | (x >> (32 - n)))
+
+#define R(i,A,B,C,D,E,F,G,H,T,Wi,Wj) do \
+ { \
+ SS1 = ROTR((ROTR((A), 12) + (E) + (T)), 7); \
+ SS2 = SS1 ^ ROTR((A), 12); \
+ D += FF##i(A,B,C) + SS2 + ((Wi) ^ (Wj)); \
+ H += GG##i(E,F,G) + SS1 + (Wi); \
+ B = ROTR((B), 9); \
+ F = ROTR((F), 19); \
+ H = P0 ((H)); \
+ } while (0)
+
+#define R1(A,B,C,D,E,F,G,H,T,Wi,Wj) R(1,A,B,C,D,E,F,G,H,T,Wi,Wj)
+#define R2(A,B,C,D,E,F,G,H,T,Wi,Wj) R(2,A,B,C,D,E,F,G,H,T,Wi,Wj)
+
+#define FF1(x, y, z) (x ^ y ^ z)
+#define FF2(x, y, z) ((x & y) | (x & z) | (y & z))
+
+#define GG1(x, y, z) (x ^ y ^ z)
+#define GG2(x, y, z) ((x & y) | ( ~x & z))
+
+/* Message expansion */
+#define P0(x) ((x) ^ ROTR((x), 9) ^ ROTR((x), 17))
+#define P1(x) ((x) ^ ROTR((x), 15) ^ ROTR((x), 23))
+
+#define I(i) ( w[i] = W[i] )
+#define W1(i) ( w[i&0x0f] )
+#define W2(i) ( w[i&0x0f] = P1(w[(i-16) & 0x0f] ^ w[(i-9) & 0x0f] ^ ROTR(w[(i-3) & 0x0f], 15)) \
+ ^ ROTR(w[(i-13) & 0x0f], 7) \
+ ^ w[(i-6) & 0x0f] )
+
+
+
+static inline uint32_t buf_get_be32(const void *_buf)
+{
+ const unsigned char *in = _buf;
+ return ((uint32_t)in[0] << 24) | ((uint32_t)in[1] << 16) | \
+ ((uint32_t)in[2] << 8) | (uint32_t)in[3];
+}
+
+/*
+ * Encode a length len*2 vector of (uint32_t) into a length len*8 vector of
+ * (uint8_t) in big-endian form.
+ */
+static void
+sm3_be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len)
+{
+ /* Encode vector, two words at a time. */
+ do {
+ be32enc(&dst[0], src[0]);
+ be32enc(&dst[4], src[1]);
+ src += 2;
+ dst += 8;
+ } while (--len);
+}
+
+/*
+ * Decode a big-endian length len*8 vector of (uint8_t) into a length
+ * len*2 vector of (uint32_t).
+ */
+static void
+sm3_be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
+{
+ /* Decode vector, two words at a time. */
+ do {
+ dst[0] = be32dec(&src[0]);
+ dst[1] = be32dec(&src[4]);
+ src += 8;
+ dst += 2;
+ } while (--len);
+}
+
+static void
+SM3_Transform(uint32_t state[static restrict 8],
+ const uint8_t block[static restrict 64],
+ uint32_t W[static restrict 64])
+{
+ uint32_t A, B, C, D, E, F, G, H, SS1, SS2;
+ uint32_t w[16];
+
+ static const uint32_t K[64] = {
+ 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
+ 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
+ 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
+ 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
+ 0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
+ 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
+ 0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
+ 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
+ };
+
+ A = state[0];
+ B = state[1];
+ C = state[2];
+ D = state[3];
+ E = state[4];
+ F = state[5];
+ G = state[6];
+ H = state[7];
+
+ sm3_be32dec_vect(W, block, 8);
+
+ R1(A, B, C, D, E, F, G, H, K[0], I(0), I(4));
+ R1(D, A, B, C, H, E, F, G, K[1], I(1), I(5));
+ R1(C, D, A, B, G, H, E, F, K[2], I(2), I(6));
+ R1(B, C, D, A, F, G, H, E, K[3], I(3), I(7));
+ R1(A, B, C, D, E, F, G, H, K[4], W1(4), I(8));
+ R1(D, A, B, C, H, E, F, G, K[5], W1(5), I(9));
+ R1(C, D, A, B, G, H, E, F, K[6], W1(6), I(10));
+ R1(B, C, D, A, F, G, H, E, K[7], W1(7), I(11));
+ R1(A, B, C, D, E, F, G, H, K[8], W1(8), I(12));
+ R1(D, A, B, C, H, E, F, G, K[9], W1(9), I(13));
+ R1(C, D, A, B, G, H, E, F, K[10], W1(10), I(14));
+ R1(B, C, D, A, F, G, H, E, K[11], W1(11), I(15));
+ R1(A, B, C, D, E, F, G, H, K[12], W1(12), W2(16));
+ R1(D, A, B, C, H, E, F, G, K[13], W1(13), W2(17));
+ R1(C, D, A, B, G, H, E, F, K[14], W1(14), W2(18));
+ R1(B, C, D, A, F, G, H, E, K[15], W1(15), W2(19));
+ R2(A, B, C, D, E, F, G, H, K[16], W1(16), W2(20));
+ R2(D, A, B, C, H, E, F, G, K[17], W1(17), W2(21));
+ R2(C, D, A, B, G, H, E, F, K[18], W1(18), W2(22));
+ R2(B, C, D, A, F, G, H, E, K[19], W1(19), W2(23));
+ R2(A, B, C, D, E, F, G, H, K[20], W1(20), W2(24));
+ R2(D, A, B, C, H, E, F, G, K[21], W1(21), W2(25));
+ R2(C, D, A, B, G, H, E, F, K[22], W1(22), W2(26));
+ R2(B, C, D, A, F, G, H, E, K[23], W1(23), W2(27));
+ R2(A, B, C, D, E, F, G, H, K[24], W1(24), W2(28));
+ R2(D, A, B, C, H, E, F, G, K[25], W1(25), W2(29));
+ R2(C, D, A, B, G, H, E, F, K[26], W1(26), W2(30));
+ R2(B, C, D, A, F, G, H, E, K[27], W1(27), W2(31));
+ R2(A, B, C, D, E, F, G, H, K[28], W1(28), W2(32));
+ R2(D, A, B, C, H, E, F, G, K[29], W1(29), W2(33));
+ R2(C, D, A, B, G, H, E, F, K[30], W1(30), W2(34));
+ R2(B, C, D, A, F, G, H, E, K[31], W1(31), W2(35));
+ R2(A, B, C, D, E, F, G, H, K[32], W1(32), W2(36));
+ R2(D, A, B, C, H, E, F, G, K[33], W1(33), W2(37));
+ R2(C, D, A, B, G, H, E, F, K[34], W1(34), W2(38));
+ R2(B, C, D, A, F, G, H, E, K[35], W1(35), W2(39));
+ R2(A, B, C, D, E, F, G, H, K[36], W1(36), W2(40));
+ R2(D, A, B, C, H, E, F, G, K[37], W1(37), W2(41));
+ R2(C, D, A, B, G, H, E, F, K[38], W1(38), W2(42));
+ R2(B, C, D, A, F, G, H, E, K[39], W1(39), W2(43));
+ R2(A, B, C, D, E, F, G, H, K[40], W1(40), W2(44));
+ R2(D, A, B, C, H, E, F, G, K[41], W1(41), W2(45));
+ R2(C, D, A, B, G, H, E, F, K[42], W1(42), W2(46));
+ R2(B, C, D, A, F, G, H, E, K[43], W1(43), W2(47));
+ R2(A, B, C, D, E, F, G, H, K[44], W1(44), W2(48));
+ R2(D, A, B, C, H, E, F, G, K[45], W1(45), W2(49));
+ R2(C, D, A, B, G, H, E, F, K[46], W1(46), W2(50));
+ R2(B, C, D, A, F, G, H, E, K[47], W1(47), W2(51));
+ R2(A, B, C, D, E, F, G, H, K[48], W1(48), W2(52));
+ R2(D, A, B, C, H, E, F, G, K[49], W1(49), W2(53));
+ R2(C, D, A, B, G, H, E, F, K[50], W1(50), W2(54));
+ R2(B, C, D, A, F, G, H, E, K[51], W1(51), W2(55));
+ R2(A, B, C, D, E, F, G, H, K[52], W1(52), W2(56));
+ R2(D, A, B, C, H, E, F, G, K[53], W1(53), W2(57));
+ R2(C, D, A, B, G, H, E, F, K[54], W1(54), W2(58));
+ R2(B, C, D, A, F, G, H, E, K[55], W1(55), W2(59));
+ R2(A, B, C, D, E, F, G, H, K[56], W1(56), W2(60));
+ R2(D, A, B, C, H, E, F, G, K[57], W1(57), W2(61));
+ R2(C, D, A, B, G, H, E, F, K[58], W1(58), W2(62));
+ R2(B, C, D, A, F, G, H, E, K[59], W1(59), W2(63));
+ R2(A, B, C, D, E, F, G, H, K[60], W1(60), W2(64));
+ R2(D, A, B, C, H, E, F, G, K[61], W1(61), W2(65));
+ R2(C, D, A, B, G, H, E, F, K[62], W1(62), W2(66));
+ R2(B, C, D, A, F, G, H, E, K[63], W1(63), W2(67));
+
+ state[0] ^= A;
+ state[1] ^= B;
+ state[2] ^= C;
+ state[3] ^= D;
+ state[4] ^= E;
+ state[5] ^= F;
+ state[6] ^= G;
+ state[7] ^= H;
+}
+
+/* Magic initialization constants. */
+static const uint32_t initial_state[8] = {
+ 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
+ 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e
+};
+
+/**
+ * SM3_Init(ctx):
+ * Initialize the SM3 context ${ctx}.
+ */
+void
+SM3_Init(SM3_CTX * ctx)
+{
+
+ /* Zero bits processed so far. */
+ ctx->count = 0;
+
+ /* Initialize state. */
+ memcpy(ctx->state, initial_state, sizeof(initial_state));
+}
+
+
+/**
+ * SM3_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the SM3 context ${ctx}.
+ */
+static void
+_SM3_Update(SM3_CTX * ctx, const void * in, size_t len,
+ uint32_t tmp32[static restrict 72])
+{
+ uint32_t r;
+ const uint8_t * src = in;
+
+ /* Return immediately if we have nothing to do. */
+ if (len == 0)
+ return;
+
+ /* Number of bytes left in the buffer from previous updates. */
+ r = (ctx->count >> 3) & 0x3f;
+
+ /* Update number of bits. */
+ ctx->count += (uint64_t)(len) << 3;
+
+ /* Handle the case where we don't need to perform any transforms. */
+ if (len < 64 - r) {
+ memcpy(&ctx->buf[r], src, len);
+ return;
+ }
+
+ /* Finish the current block. */
+ memcpy(&ctx->buf[r], src, 64 - r);
+ SM3_Transform(ctx->state, ctx->buf, &tmp32[0]);
+ src += 64 - r;
+ len -= 64 - r;
+
+ /* Perform complete blocks. */
+ while (len >= 64) {
+ SM3_Transform(ctx->state, src, &tmp32[0]);
+ src += 64;
+ len -= 64;
+ }
+
+ /* Copy left over data into buffer. */
+ memcpy(ctx->buf, src, len);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+SM3_Update(SM3_CTX * ctx, const void * in, size_t len)
+{
+ uint32_t tmp32[72];
+
+ /* Call the real function. */
+ _SM3_Update(ctx, in, len, tmp32);
+
+ /* Clean the stack. */
+ explicit_bzero(tmp32, 288);
+}
+
+static const uint8_t PAD[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Add padding and terminating bit-count. */
+static void
+SM3_Pad(SM3_CTX * ctx, uint32_t tmp32[static restrict 72])
+{
+ size_t r;
+
+ /* Figure out how many bytes we have buffered. */
+ r = (ctx->count >> 3) & 0x3f;
+
+ /* Pad to 56 mod 64, transforming if we finish a block en route. */
+ if (r < 56) {
+ /* Pad to 56 mod 64. */
+ memcpy(&ctx->buf[r], PAD, 56 - r);
+ } else {
+ /* Finish the current block and mix. */
+ memcpy(&ctx->buf[r], PAD, 64 - r);
+ SM3_Transform(ctx->state, ctx->buf, &tmp32[0]);
+
+ /* The start of the final block is all zeroes. */
+ memset(&ctx->buf[0], 0, 56);
+ }
+
+ /* Add the terminating bit-count. */
+ be64enc(&ctx->buf[56], ctx->count);
+
+ /* Mix in the final block. */
+ SM3_Transform(ctx->state, ctx->buf, &tmp32[0]);
+}
+/**
+ * SM3_Final(digest, ctx):
+ * Output the SM3 hash of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+static void
+_SM3_Final(uint8_t digest[32], SM3_CTX * ctx, uint32_t tmp32[static restrict 72])
+{
+
+ /* Add padding. */
+ SM3_Pad(ctx, tmp32);
+
+ /* Write the hash. */
+ sm3_be32enc_vect(digest, ctx->state, 4);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+SM3_Final(uint8_t digest[32], SM3_CTX * ctx)
+{
+ uint32_t tmp32[72];
+
+ /* Call the real function. */
+ _SM3_Final(digest, ctx, tmp32);
+
+ /* Clear the context state. */
+ explicit_bzero(ctx, sizeof(SM3_CTX));
+
+ /* Clean the stack. */
+ explicit_bzero(tmp32, 288);
+}
+
+/**
+ * SM3_Buf(in, len, digest):
+ * Compute the SM3 hash of ${len} bytes from ${in} and write it to ${digest}.
+ */
+void
+SM3_Buf(const void * in, size_t len, uint8_t digest[32])
+{
+ SM3_CTX ctx;
+ uint32_t tmp32[72];
+
+ SM3_Init(&ctx);
+ _SM3_Update(&ctx, in, len, tmp32);
+ _SM3_Final(digest, &ctx, tmp32);
+
+ /* Clean the stack. */
+ explicit_bzero(&ctx, sizeof(SM3_CTX));
+ explicit_bzero(tmp32, 288);
+}
+#endif /* INCLUDE_sm3crypt */
\ No newline at end of file
diff -Naur libxcrypt-4.4.28.orig/lib/alg-sm3.h libxcrypt-4.4.28/lib/alg-sm3.h
--- libxcrypt-4.4.28.orig/lib/alg-sm3.h 1970-01-01 08:00:00.000000000 +0800
+++ libxcrypt-4.4.28/lib/alg-sm3.h 2023-03-06 15:05:51.601787579 +0800
@@ -0,0 +1,51 @@
+#ifndef _SM3_H_
+#define _SM3_H_
+
+#include "crypt-port.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * Use #defines in order to avoid namespace collisions with anyone else's
+ * SM3 code (e.g., the code in OpenSSL).
+ */
+#define SM3_Init libcperciva_SM3_Init
+#define SM3_Update libcperciva_SM3_Update
+#define SM3_Final libcperciva_SM3_Final
+#define SM3_Buf libcperciva_SM3_Buf
+#define SM3_CTX libcperciva_SM3_CTX
+
+/* Context structure for SM3 operations. */
+typedef struct {
+ uint32_t state[8];
+ uint64_t count;
+ uint8_t buf[64];
+} SM3_CTX;
+
+/**
+ * SM3_Init(ctx):
+ * Initialize the SM3 context ${ctx}.
+ */
+extern void SM3_Init(SM3_CTX *);
+
+/**
+ * SM3_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the SM3 context ${ctx}.
+ */
+extern void SM3_Update(SM3_CTX *, const void *, size_t);
+
+/**
+ * SM3_Final(digest, ctx):
+ * Output the SM3 hash of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+extern void SM3_Final(uint8_t[32], SM3_CTX *);
+
+/**
+ * SM3_Buf(in, len, digest):
+ * Compute the SM3 hash of ${len} bytes from ${in} and write it to ${digest}.
+ */
+extern void SM3_Buf(const void *, size_t, uint8_t[32]);
+
+#endif /* !_SM3_H_ */
diff -Naur libxcrypt-4.4.28.orig/lib/crypt-port.h libxcrypt-4.4.28/lib/crypt-port.h
--- libxcrypt-4.4.28.orig/lib/crypt-port.h 2023-03-06 15:05:34.357791337 +0800
+++ libxcrypt-4.4.28/lib/crypt-port.h 2023-03-06 15:05:51.601787579 +0800
@@ -357,7 +357,7 @@
#define libcperciva_SHA512_Buf _crypt_SHA512_Buf
#endif
-#if INCLUDE_md5crypt || INCLUDE_sha256crypt || INCLUDE_sha512crypt
+#if INCLUDE_md5crypt || INCLUDE_sha256crypt || INCLUDE_sha512crypt || INCLUDE_sm3crypt
#define gensalt_sha_rn _crypt_gensalt_sha_rn
#endif
@@ -392,6 +392,13 @@
#define libcperciva_SHA256_Buf _crypt_SHA256_Buf
#endif
+#if INCLUDE_sm3crypt
+#define libcperciva_SM3_Init _crypt_SM3_Init
+#define libcperciva_SM3_Update _crypt_SM3_Update
+#define libcperciva_SM3_Final _crypt_SM3_Final
+#define libcperciva_SM3_Buf _crypt_SM3_Buf
+#endif
+
#if INCLUDE_gost_yescrypt
#define GOST34112012Init _crypt_GOST34112012_Init
#define GOST34112012Update _crypt_GOST34112012_Update
@@ -438,7 +445,7 @@
extern bool get_random_bytes (void *buf, size_t buflen);
/* Generate a setting string in the format common to md5crypt,
- sha256crypt, and sha512crypt. */
+ sha256crypt, sha512crypt and sm3crypt. */
extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount,
unsigned long mincount, unsigned long maxcount,
unsigned long count,
diff -Naur libxcrypt-4.4.28.orig/lib/crypt-sm3.c libxcrypt-4.4.28/lib/crypt-sm3.c
--- libxcrypt-4.4.28.orig/lib/crypt-sm3.c 1970-01-01 08:00:00.000000000 +0800
+++ libxcrypt-4.4.28/lib/crypt-sm3.c 2023-03-06 19:56:40.440792088 +0800
@@ -0,0 +1,346 @@
+#include "crypt-port.h"
+#include "alg-sm3.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if INCLUDE_sm3crypt
+
+/* Define our magic string to mark salt for SM3 "encryption"
+ replacement. */
+static const char sm3_salt_prefix[] = "$sm3$";
+
+/* Prefix for optional rounds specification. */
+static const char sm3_rounds_prefix[] = "rounds=";
+
+/* Maximum salt string length. */
+#define SALT_LEN_MAX 16
+/* Default number of rounds if not explicitly specified. */
+#define ROUNDS_DEFAULT 5000
+/* Minimum number of rounds. */
+#define ROUNDS_MIN 1000
+/* Maximum number of rounds. */
+#define ROUNDS_MAX 999999999
+
+/* The maximum possible length of a SM3-hashed password string,
+ including the terminating NUL character. Prefix (including its NUL)
+ + rounds tag ("rounds=$" = "rounds=\0") + strlen(ROUNDS_MAX)
+ + salt (up to SALT_LEN_MAX chars) + '$' + hash (43 chars). */
+
+#define LENGTH_OF_NUMBER(n) (sizeof #n - 1)
+
+#define SM3_HASH_LENGTH \
+ (sizeof (sm3_salt_prefix) + sizeof (sm3_rounds_prefix) + \
+ LENGTH_OF_NUMBER (ROUNDS_MAX) + SALT_LEN_MAX + 1 + 43)
+
+static_assert (SM3_HASH_LENGTH <= CRYPT_OUTPUT_SIZE,
+ "CRYPT_OUTPUT_SIZE is too small for SM3");
+
+/* A sm3_buffer holds all of the sensitive intermediate data. */
+struct sm3_buffer
+{
+ SM3_CTX ctx;
+ uint8_t result[32];
+ uint8_t p_bytes[32];
+ uint8_t s_bytes[32];
+};
+
+static_assert (sizeof (struct sm3_buffer) <= ALG_SPECIFIC_SIZE,
+ "ALG_SPECIFIC_SIZE is too small for SM3");
+
+
+/* Feed CTX with LEN bytes of a virtual byte sequence consisting of
+ BLOCK repeated over and over indefinitely. */
+static void
+SM3_Update_recycled (SM3_CTX *ctx,
+ unsigned char block[32], size_t len)
+{
+ size_t cnt;
+ for (cnt = len; cnt >= 32; cnt -= 32)
+ SM3_Update (ctx, block, 32);
+ SM3_Update (ctx, block, cnt);
+}
+
+void
+crypt_sm3crypt_rn (const char *phrase, size_t phr_size,
+ const char *setting, size_t ARG_UNUSED (set_size),
+ uint8_t *output, size_t out_size,
+ void *scratch, size_t scr_size)
+{
+ /* This shouldn't ever happen, but... */
+ if (out_size < SM3_HASH_LENGTH
+ || scr_size < sizeof (struct sm3_buffer))
+ {
+ errno = ERANGE;
+ return;
+ }
+
+ struct sm3_buffer *buf = scratch;
+ SM3_CTX *ctx = &buf->ctx;
+ uint8_t *result = buf->result;
+ uint8_t *p_bytes = buf->p_bytes;
+ uint8_t *s_bytes = buf->s_bytes;
+ char *cp = (char *)output;
+ const char *salt = setting;
+
+ size_t salt_size;
+ size_t cnt;
+ /* Default number of rounds. */
+ size_t rounds = ROUNDS_DEFAULT;
+ bool rounds_custom = false;
+
+ /* Find beginning of salt string. The prefix should normally always
+ be present. Just in case it is not. */
+ if (strncmp (sm3_salt_prefix, salt, sizeof (sm3_salt_prefix) - 1) == 0)
+ /* Skip salt prefix. */
+ salt += sizeof (sm3_salt_prefix) - 1;
+
+ if (strncmp (salt, sm3_rounds_prefix, sizeof (sm3_rounds_prefix) - 1)
+ == 0)
+ {
+ const char *num = salt + sizeof (sm3_rounds_prefix) - 1;
+ /* Do not allow an explicit setting of zero rounds, nor of the
+ default number of rounds, nor leading zeroes on the rounds. */
+ if (!(*num >= '1' && *num <= '9'))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ errno = 0;
+ char *endp;
+ rounds = strtoul (num, &endp, 10);
+ if (endp == num || *endp != '$'
+ || rounds < ROUNDS_MIN
+ || rounds > ROUNDS_MAX
+ || errno)
+ {
+ errno = EINVAL;
+ return;
+ }
+ salt = endp + 1;
+ rounds_custom = true;
+ }
+
+ /* The salt ends at the next '$' or the end of the string.
+ Ensure ':' does not appear in the salt (it is used as a separator in /etc/passwd).
+ Also check for '\n', as in /etc/passwd the whole parameters of the user data must
+ be on a single line. */
+ salt_size = strcspn (salt, "$:\n");
+ if (!(salt[salt_size] == '$' || !salt[salt_size]))
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ /* Ensure we do not use more salt than SALT_LEN_MAX. */
+ if (salt_size > SALT_LEN_MAX)
+ salt_size = SALT_LEN_MAX;
+
+ /* Compute alternate SM3 sum with input PHRASE, SALT, and PHRASE. The
+ final result will be added to the first context. */
+ SM3_Init (ctx);
+
+ /* Add phrase. */
+ SM3_Update (ctx, phrase, phr_size);
+
+ /* Add salt. */
+ SM3_Update (ctx, salt, salt_size);
+
+ /* Add phrase again. */
+ SM3_Update (ctx, phrase, phr_size);
+
+ /* Now get result of this (32 bytes). */
+ SM3_Final (result, ctx);
+
+ /* Prepare for the real work. */
+ SM3_Init (ctx);
+
+ /* Add the phrase string. */
+ SM3_Update (ctx, phrase, phr_size);
+
+ /* The last part is the salt string. This must be at most 8
+ characters and it ends at the first `$' character (for
+ compatibility with existing implementations). */
+ SM3_Update (ctx, salt, salt_size);
+
+ /* Add for any character in the phrase one byte of the alternate sum. */
+ for (cnt = phr_size; cnt > 32; cnt -= 32)
+ SM3_Update (ctx, result, 32);
+ SM3_Update (ctx, result, cnt);
+
+ /* Take the binary representation of the length of the phrase and for every
+ 1 add the alternate sum, for every 0 the phrase. */
+ for (cnt = phr_size; cnt > 0; cnt >>= 1)
+ if ((cnt & 1) != 0)
+ SM3_Update (ctx, result, 32);
+ else
+ SM3_Update (ctx, phrase, phr_size);
+
+ /* Create intermediate result. */
+ SM3_Final (result, ctx);
+
+ /* Start computation of P byte sequence. */
+ SM3_Init (ctx);
+
+ /* For every character in the password add the entire password. */
+ for (cnt = 0; cnt < phr_size; ++cnt)
+ SM3_Update (ctx, phrase, phr_size);
+
+ /* Finish the digest. */
+ SM3_Final (p_bytes, ctx);
+
+ /* Start computation of S byte sequence. */
+ SM3_Init (ctx);
+
+ /* For every character in the password add the entire password. */
+ for (cnt = 0; cnt < (size_t) 16 + (size_t) result[0]; ++cnt)
+ SM3_Update (ctx, salt, salt_size);
+
+ /* Finish the digest. */
+ SM3_Final (s_bytes, ctx);
+
+ /* Repeatedly run the collected hash value through SM3 to burn
+ CPU cycles. */
+ for (cnt = 0; cnt < rounds; ++cnt)
+ {
+ /* New context. */
+ SM3_Init (ctx);
+
+ /* Add phrase or last result. */
+ if ((cnt & 1) != 0)
+ SM3_Update_recycled (ctx, p_bytes, phr_size);
+ else
+ SM3_Update (ctx, result, 32);
+
+ /* Add salt for numbers not divisible by 3. */
+ if (cnt % 3 != 0)
+ SM3_Update_recycled (ctx, s_bytes, salt_size);
+
+ /* Add phrase for numbers not divisible by 7. */
+ if (cnt % 7 != 0)
+ SM3_Update_recycled (ctx, p_bytes, phr_size);
+
+ /* Add phrase or last result. */
+ if ((cnt & 1) != 0)
+ SM3_Update (ctx, result, 32);
+ else
+ SM3_Update_recycled (ctx, p_bytes, phr_size);
+
+ /* Create intermediate result. */
+ SM3_Final (result, ctx);
+ }
+
+ /* Now we can construct the result string. It consists of four
+ parts, one of which is optional. We already know that there
+ is sufficient space at CP for the longest possible result string. */
+ memcpy (cp, sm3_salt_prefix, sizeof (sm3_salt_prefix) - 1);
+ cp += sizeof (sm3_salt_prefix) - 1;
+
+ if (rounds_custom)
+ {
+ int n = snprintf (cp,
+ SM3_HASH_LENGTH - (sizeof (sm3_salt_prefix) - 1),
+ "%s%zu$", sm3_rounds_prefix, rounds);
+ cp += n;
+ }
+
+ memcpy (cp, salt, salt_size);
+ cp += salt_size;
+ *cp++ = '$';
+
+#define b64_from_24bit(B2, B1, B0, N) \
+ do { \
+ unsigned int w = ((((unsigned int)(B2)) << 16) | \
+ (((unsigned int)(B1)) << 8) | \
+ ((unsigned int)(B0))); \
+ int n = (N); \
+ while (n-- > 0) \
+ { \
+ *cp++ = b64t[w & 0x3f]; \
+ w >>= 6; \
+ } \
+ } while (0)
+
+ b64_from_24bit (result[0], result[10], result[20], 4);
+ b64_from_24bit (result[21], result[1], result[11], 4);
+ b64_from_24bit (result[12], result[22], result[2], 4);
+ b64_from_24bit (result[3], result[13], result[23], 4);
+ b64_from_24bit (result[24], result[4], result[14], 4);
+ b64_from_24bit (result[15], result[25], result[5], 4);
+ b64_from_24bit (result[6], result[16], result[26], 4);
+ b64_from_24bit (result[27], result[7], result[17], 4);
+ b64_from_24bit (result[18], result[28], result[8], 4);
+ b64_from_24bit (result[9], result[19], result[29], 4);
+ b64_from_24bit (0, result[31], result[30], 3);
+
+ *cp = '\0';
+}
+
+void
+gensalt_sm3crypt_rn (unsigned long count,
+ const uint8_t *rbytes, size_t nrbytes,
+ uint8_t *output, size_t output_size)
+{
+ /* We will use more rbytes if available, but at least this much is
+ required. */
+ if (nrbytes < 5)
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ if (count == 0)
+ count = ROUNDS_DEFAULT;
+ if (count < ROUNDS_MIN)
+ count = ROUNDS_MIN;
+ if (count > ROUNDS_MAX)
+ count = ROUNDS_MAX;
+
+ /* Compute how much space we need. */
+ size_t output_len = 10; /* $sm3$ssss\0 */
+ if (count != ROUNDS_DEFAULT)
+ {
+ output_len += 9; /* rounds=1$ */
+ for (unsigned long ceiling = 10; ceiling < count; ceiling *= 10)
+ output_len += 1;
+ }
+ if (output_size < output_len)
+ {
+ errno = ERANGE;
+ return;
+ }
+
+ size_t written;
+ if (count == ROUNDS_DEFAULT)
+ written = (size_t) snprintf ((char *)output, output_size, "$sm3$");
+ else
+ written = (size_t) snprintf ((char *)output, output_size, "$sm3$rounds=%lu$", count);
+
+ /* The length calculation above should ensure that this is always true. */
+ assert (written + 5 < output_size);
+
+ size_t used_rbytes = 0;
+ while (written + 5 < output_size &&
+ used_rbytes + 3 < nrbytes &&
+ (used_rbytes * 4 / 3) < SALT_LEN_MAX)
+ {
+ unsigned long value =
+ ((unsigned long) (unsigned char) rbytes[used_rbytes + 0] << 0) |
+ ((unsigned long) (unsigned char) rbytes[used_rbytes + 1] << 8) |
+ ((unsigned long) (unsigned char) rbytes[used_rbytes + 2] << 16);
+
+ output[written + 0] = ascii64[value & 0x3f];
+ output[written + 1] = ascii64[(value >> 6) & 0x3f];
+ output[written + 2] = ascii64[(value >> 12) & 0x3f];
+ output[written + 3] = ascii64[(value >> 18) & 0x3f];
+
+ written += 4;
+ used_rbytes += 3;
+ }
+
+ output[written] = '\0';
+}
+
+#endif
diff -Naur libxcrypt-4.4.28.orig/lib/hashes.conf libxcrypt-4.4.28/lib/hashes.conf
--- libxcrypt-4.4.28.orig/lib/hashes.conf 2023-03-06 15:05:34.358791337 +0800
+++ libxcrypt-4.4.28/lib/hashes.conf 2023-03-06 15:05:51.602787579 +0800
@@ -49,6 +49,7 @@
sha512crypt $6$ 15 STRONG,DEFAULT,GLIBC,FREEBSD,SOLARIS
sha256crypt $5$ 15 GLIBC,FREEBSD,SOLARIS
sha1crypt $sha1 20 NETBSD
+sm3crypt $sm3$ 15 STRONG
sunmd5 $md5 8 SOLARIS
md5crypt $1$ 9 GLIBC,FREEBSD,NETBSD,OPENBSD,SOLARIS
nt $3$ 1 FREEBSD
diff -Naur libxcrypt-4.4.28.orig/test/alg-sm3.c libxcrypt-4.4.28/test/alg-sm3.c
--- libxcrypt-4.4.28.orig/test/alg-sm3.c 1970-01-01 08:00:00.000000000 +0800
+++ libxcrypt-4.4.28/test/alg-sm3.c 2023-03-06 15:05:51.602787579 +0800
@@ -0,0 +1,137 @@
+#include "crypt-port.h"
+#include "alg-sm3.h"
+
+#include <stdio.h>
+
+#if INCLUDE_sm3crypt
+
+static const struct
+{
+ const char *input;
+ const char result[32];
+} tests[] =
+{
+ /* Test vectors from SM3 Cryptographic Hash Algorithm: appendix A.1 */
+ {
+ "abc",
+ "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1\xf2\xd4\x6b\xdc\x10\xe4\xe2"
+ "\x41\x67\xc4\x87\x5c\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b\xa8\xe0"
+ },
+ {
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x63\x9b\x6c\xc5\xe6\x4d\x9e\x37\xa3\x90\xb1\x92\xdf\x4f\xa1\xea"
+ "\x07\x20\xab\x74\x7f\xf6\x92\xb9\xf3\x8c\x4e\x66\xad\x7b\x8c\x05"
+ },
+ {
+ "",
+ "\x1a\xb2\x1d\x83\x55\xcf\xa1\x7f\x8e\x61\x19\x48\x31\xe8\x1a\x8f"
+ "\x22\xbe\xc8\xc7\x28\xfe\xfb\x74\x7e\xd0\x35\xeb\x50\x82\xaa\x2b"
+ },
+ {
+ "a",
+ "\x62\x34\x76\xac\x18\xf6\x5a\x29\x09\xe4\x3c\x7f\xec\x61\xb4\x9c"
+ "\x7e\x76\x4a\x91\xa1\x8c\xcb\x82\xf1\x91\x7a\x29\xc8\x6c\x5e\x88"
+ },
+ {
+ "message digest",
+ "\xc5\x22\xa9\x42\xe8\x9b\xd8\x0d\x97\xdd\x66\x6e\x7a\x55\x31\xb3"
+ "\x61\x88\xc9\x81\x71\x49\xe9\xb2\x58\xdf\xe5\x1e\xce\x98\xed\x77"
+ },
+ {
+ "abcdefghijklmnopqrstuvwxyz",
+ "\xb8\x0f\xe9\x7a\x4d\xa2\x4a\xfc\x27\x75\x64\xf6\x6a\x35\x9e\xf4"
+ "\x40\x46\x2a\xd2\x8d\xcc\x6d\x63\xad\xb2\x4d\x5c\x20\xa6\x15\x95"
+ },
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "\x29\x71\xd1\x0c\x88\x42\xb7\x0c\x97\x9e\x55\x06\x34\x80\xc5\x0b"
+ "\xac\xff\xd9\x0e\x98\xe2\xe6\x0d\x25\x12\xab\x8a\xbf\xdf\xce\xc5"
+ },
+ {
+ "123456789012345678901234567890123456789012345678901234567890"
+ "12345678901234567890",
+ "\xad\x81\x80\x53\x21\xf3\xe6\x9d\x25\x12\x35\xbf\x88\x6a\x56\x48"
+ "\x44\x87\x3b\x56\xdd\x7d\xde\x40\x0f\x05\x5b\x7d\xde\x39\x30\x7a"
+ }
+};
+
+
+static void
+report_failure(int n, const char *tag,
+ const char expected[32], uint8_t actual[32])
+{
+ int i;
+ printf ("FAIL: test %d (%s):\n exp:", n, tag);
+ for (i = 0; i < 32; i++)
+ {
+ if (i % 4 == 0)
+ putchar (' ');
+ printf ("%02x", (unsigned int)(unsigned char)expected[i]);
+ }
+ printf ("\n got:");
+ for (i = 0; i < 32; i++)
+ {
+ if (i % 4 == 0)
+ putchar (' ');
+ printf ("%02x", (unsigned int)(unsigned char)actual[i]);
+ }
+ putchar ('\n');
+ putchar ('\n');
+}
+
+int
+main (void)
+{
+ SM3_CTX ctx;
+ uint8_t sum[32];
+ int result = 0;
+ int cnt;
+ int i;
+
+ for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt)
+ {
+ SM3_Buf (tests[cnt].input, strlen (tests[cnt].input), sum);
+ if (memcmp (tests[cnt].result, sum, 32) != 0)
+ {
+ report_failure (cnt, "all at once", tests[cnt].result, sum);
+ result = 1;
+ }
+
+ SM3_Init (&ctx);
+ for (i = 0; tests[cnt].input[i] != '\0'; ++i)
+ SM3_Update (&ctx, &tests[cnt].input[i], 1);
+ SM3_Final (sum, &ctx);
+ if (memcmp (tests[cnt].result, sum, 32) != 0)
+ {
+ report_failure (cnt, "byte by byte", tests[cnt].result, sum);
+ result = 1;
+ }
+ }
+
+ char buf[1000];
+ memset (buf, 'a', sizeof (buf));
+ SM3_Init (&ctx);
+ for (i = 0; i < 1000; ++i)
+ SM3_Update (&ctx, buf, sizeof (buf));
+ SM3_Final (sum, &ctx);
+ static const char expected[32] =
+ "\xc8\xaa\xf8\x94\x29\x55\x40\x29\xe2\x31\x94\x1a\x2a\xcc\x0a\xd6"
+ "\x1f\xf2\xa5\xac\xd8\xfa\xdd\x25\x84\x7a\x3a\x73\x2b\x3b\x02\xc3";
+ if (memcmp (expected, sum, 32) != 0)
+ {
+ report_failure (cnt, "block by block", expected, sum);
+ result = 1;
+ }
+
+ return result;
+}
+
+#else
+
+int
+main (void)
+{
+ return 77; /* UNSUPPORTED */
+}
+
+#endif
diff -Naur libxcrypt-4.4.28.orig/test/badsalt.c libxcrypt-4.4.28/test/badsalt.c
--- libxcrypt-4.4.28.orig/test/badsalt.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/badsalt.c 2023-03-06 15:05:51.602787579 +0800
@@ -77,6 +77,7 @@
static bool vt_varsuffix(const struct valid_setting *, const char *);
static bool vt_sunmd5(const struct valid_setting *, const char *);
static bool vt_sha2gnu(const struct valid_setting *, const char *);
+static bool vt_sm3crypt(const struct valid_setting *, const char *);
static bool vt_yescrypt(const struct valid_setting *, const char *);
/* shorthands for use in valid_cases */
@@ -129,6 +130,8 @@
Vtn(sha256crypt, rounds, sha2gnu, "$5$rounds=1000$MJHnaAkegEVYHsFK$" ),
Vtn(sha512crypt, plain, sha2gnu, "$6$MJHnaAkegEVYHsFK$" ),
Vtn(sha512crypt, rounds, sha2gnu, "$6$rounds=1000$MJHnaAkegEVYHsFK$" ),
+ Vtn(sm3crypt, plain, sm3crypt, "$sm3$MJHnaAkegEVYHsFF$" ),
+ Vtn(sm3crypt, rounds, sm3crypt, "$sm3$rounds=1000$MJHnaAkegEVYHsFK$" ),
V (bcrypt, "$2b$04$UBVLHeMpJ/QQCv3XqJx8zO" ),
V (bcrypt_a, "$2a$04$UBVLHeMpJ/QQCv3XqJx8zO" ),
V (bcrypt_x, "$2x$04$UBVLHeMpJ/QQCv3XqJx8zO" ),
@@ -198,6 +201,10 @@
{ "sha512 low rounds", "$6$rounds=0$MJHnaAkegEVYHsFK$" },
{ "sha512 octal rounds", "$6$rounds=0100$MJHnaAkegEVYHsFK$" },
{ "sha512 high rounds", "$6$rounds=4294967295$MJHnaAkegEVYHsFK$" },
+ { "sm3 absent rounds", "$sm3$rounds=$MJHnaAkegEVYHsFK$" },
+ { "sm3 low rounds", "$sm3$rounds=0$MJHnaAkegEVYHsFK$" },
+ { "sm3 octal rounds", "$sm3$rounds=0100$MJHnaAkegEVYHsFK$" },
+ { "sm3 high rounds", "$sm3$rounds=4294967295$MJHnaAkegEVYHsFK$" },
{ "bcrypt no subtype", "$2$04$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt_b low rounds", "$2b$03$UBVLHeMpJ/QQCv3XqJx8zO" },
{ "bcrypt_b high rounds", "$2b$32$UBVLHeMpJ/QQCv3XqJx8zO" },
@@ -232,7 +239,7 @@
return strlen(truncated) >= original->is_valid_trunc_param;
}
-/* Special validity rule for sunmd5, sha256crypt, and sha512crypt: ... */
+/* Special validity rule for sunmd5, sha256crypt, sha512crypt and sm3crypt: ... */
static bool
vt_roundseq(const char *truncated, size_t minlen, size_t roundslen,
const char *roundstag1, const char *roundstag2)
@@ -268,7 +275,7 @@
"$md5,rounds=", 0);
}
-/* Special validity rule for sha256crypt and sha512crypt. */
+/* Special validity rule for sha256crypt, sha512crypt. */
static bool
vt_sha2gnu(const struct valid_setting *ARG_UNUSED(original),
const char *truncated)
@@ -277,6 +284,15 @@
"$5$rounds=", "$6$rounds=");
}
+/* Special validity rule for sm3crypt. */
+static bool
+vt_sm3crypt(const struct valid_setting *ARG_UNUSED(original),
+ const char *truncated)
+{
+ return vt_roundseq(truncated, strlen("$sm3$"), strlen("$sm3$rounds="),
+ "$sm3$rounds=", 0);
+}
+
/* Special validity rule for yescrypt and gost_yescrypt: ... */
static bool
vt_yescrypt(const struct valid_setting *ARG_UNUSED(original),
diff -Naur libxcrypt-4.4.28.orig/test/badsetting.c libxcrypt-4.4.28/test/badsetting.c
--- libxcrypt-4.4.28.orig/test/badsetting.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/badsetting.c 2023-03-06 15:05:51.602787579 +0800
@@ -110,6 +110,15 @@
{ "$6$", 0, 0, 0 },
#endif
+ /* SM3 */
+#if INCLUDE_sm3crypt
+ { "$sm3", 0, 0, 0 }, // truncated prefix
+ { "$sm3$", 0, 2, 0 }, // inadequate rbytes
+ { "$sm3$", 0, 0, 4 }, // inadequate osize
+#else
+ { "$sm3$", 0, 0, 0 },
+#endif
+
/* bcrypt */
#if INCLUDE_bcrypt
{ "$2", 0, 0, 0 }, // truncated prefix
diff -Naur libxcrypt-4.4.28.orig/test/checksalt.c libxcrypt-4.4.28/test/checksalt.c
--- libxcrypt-4.4.28.orig/test/checksalt.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/checksalt.c 2023-03-06 15:05:51.602787579 +0800
@@ -73,6 +73,11 @@
#else
{ "$6$", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
#endif
+#if INCLUDE_sm3crypt
+ { "$sm3$", CRYPT_SALT_OK, CRYPT_SALT_OK, CRYPT_SALT_OK },
+#else
+ { "$sm3$", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
+#endif
#if INCLUDE_bcrypt
{ "$2b$", CRYPT_SALT_OK, CRYPT_SALT_OK, CRYPT_SALT_OK },
#else
diff -Naur libxcrypt-4.4.28.orig/test/crypt-badargs.c libxcrypt-4.4.28/test/crypt-badargs.c
--- libxcrypt-4.4.28.orig/test/crypt-badargs.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/crypt-badargs.c 2023-03-06 15:05:51.603787579 +0800
@@ -54,6 +54,10 @@
"$6$MJHnaAkegEVYHsFK",
"$6$rounds=10191$MJHnaAkegEVYHsFK",
#endif
+#if INCLUDE_sm3crypt
+ "$sm3$MJHnaAkegEVYHsFK",
+ "$sm3$rounds=10191$MJHnaAkegEVYHsFK",
+#endif
#if INCLUDE_bcrypt_a
"$2a$05$UBVLHeMpJ/QQCv3XqJx8zO",
#endif
diff -Naur libxcrypt-4.4.28.orig/test/gensalt-extradata.c libxcrypt-4.4.28/test/gensalt-extradata.c
--- libxcrypt-4.4.28.orig/test/gensalt-extradata.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/gensalt-extradata.c 2023-03-06 15:05:51.603787579 +0800
@@ -64,6 +64,9 @@
#if INCLUDE_sha512crypt
{ "$6$", 7019, 1120211 },
#endif
+#if INCLUDE_sm3crypt
+ { "$sm3$", 7019, 1120211 },
+#endif
#if INCLUDE_bcrypt
{ "$2b$", 7, 11 },
#endif
diff -Naur libxcrypt-4.4.28.orig/test/gensalt.c libxcrypt-4.4.28/test/gensalt.c
--- libxcrypt-4.4.28.orig/test/gensalt.c 2023-03-06 15:05:34.359791336 +0800
+++ libxcrypt-4.4.28/test/gensalt.c 2023-03-06 15:05:51.603787579 +0800
@@ -170,6 +170,36 @@
"$6$rounds=999999999$UqGBkVu01rurVZqg"
};
#endif
+#if INCLUDE_sm3crypt
+static const char *const sm3_expected_output[] =
+{
+ "$sm3$MJHnaAkegEVYHsFK",
+ "$sm3$PKXc3hCOSyMqdaEQ",
+ "$sm3$ZAFlICwYRETzIzIj",
+ "$sm3$UqGBkVu01rurVZqg"
+};
+static const char *const sm3_expected_output_r[] =
+{
+ "$sm3$rounds=10191$MJHnaAkegEVYHsFK",
+ "$sm3$rounds=10191$PKXc3hCOSyMqdaEQ",
+ "$sm3$rounds=10191$ZAFlICwYRETzIzIj",
+ "$sm3$rounds=10191$UqGBkVu01rurVZqg"
+};
+static const char *const sm3_expected_output_l[] =
+{
+ "$sm3$rounds=1000$MJHnaAkegEVYHsFK",
+ "$sm3$rounds=1000$PKXc3hCOSyMqdaEQ",
+ "$sm3$rounds=1000$ZAFlICwYRETzIzIj",
+ "$sm3$rounds=1000$UqGBkVu01rurVZqg"
+};
+static const char *const sm3_expected_output_h[] =
+{
+ "$sm3$rounds=999999999$MJHnaAkegEVYHsFK",
+ "$sm3$rounds=999999999$PKXc3hCOSyMqdaEQ",
+ "$sm3$rounds=999999999$ZAFlICwYRETzIzIj",
+ "$sm3$rounds=999999999$UqGBkVu01rurVZqg"
+};
+#endif
#if INCLUDE_bcrypt
static const char *const bcrypt_b_expected_output[] =
{
@@ -291,7 +321,7 @@
};
// For all hashing methods with a linear cost parameter (that is,
-// DES/BSD, MD5/Sun, SHA1, SHA256, and SHA512), crypt_gensalt will
+// DES/BSD, MD5/Sun, SHA1, SHA256, SHA512 and SM3), crypt_gensalt will
// accept any value in the range of 'unsigned long' and clip it to the
// actual valid range.
#define MIN_LINEAR_COST 1
@@ -344,6 +374,12 @@
{ "$6$", sha512_expected_output_l, 31, 0, MIN_LINEAR_COST },
{ "$6$", sha512_expected_output_h, 36, 0, MAX_LINEAR_COST },
#endif
+#if INCLUDE_sm3crypt
+ { "$sm3$", sm3_expected_output, 21, 0, 0 },
+ { "$sm3$", sm3_expected_output_r, 34, 0, 10191 },
+ { "$sm3$", sm3_expected_output_l, 33, 0, MIN_LINEAR_COST },
+ { "$sm3$", sm3_expected_output_h, 38, 0, MAX_LINEAR_COST },
+#endif
#if INCLUDE_bcrypt
{ "$2b$", bcrypt_b_expected_output, 29, 0, 0 },
// bcrypt always emits a cost parameter.
@@ -386,6 +422,8 @@
# define EXPECTED_DEFAULT_PREFIX "$2b$"
#elif INCLUDE_sha512crypt
# define EXPECTED_DEFAULT_PREFIX "$6$"
+#elif INCLUDE_sm3crypt
+# define EXPECTED_DEFAULT_PREFIX "$sm3$"
#endif
#if CRYPT_GENSALT_IMPLEMENTS_DEFAULT_PREFIX
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。