Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
0004  * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
0005  *
0006  * Copyright (C) 2017 ARM Limited or its affiliates.
0007  * Copyright (C) 2017 Gilad Ben-Yossef <gilad@benyossef.com>
0008  * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <asm/unaligned.h>
0013 #include <crypto/sm3.h>
0014 
0015 static const u32 ____cacheline_aligned K[64] = {
0016     0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
0017     0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
0018     0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
0019     0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
0020     0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
0021     0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
0022     0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
0023     0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
0024     0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
0025     0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
0026     0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
0027     0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
0028     0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
0029     0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
0030     0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
0031     0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
0032 };
0033 
0034 /*
0035  * Transform the message X which consists of 16 32-bit-words. See
0036  * GM/T 004-2012 for details.
0037  */
0038 #define R(i, a, b, c, d, e, f, g, h, t, w1, w2)         \
0039     do {                            \
0040         ss1 = rol32((rol32((a), 12) + (e) + (t)), 7);   \
0041         ss2 = ss1 ^ rol32((a), 12);         \
0042         d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2));    \
0043         h += GG ## i(e, f, g) + ss1 + (w1);     \
0044         b = rol32((b), 9);              \
0045         f = rol32((f), 19);             \
0046         h = P0((h));                    \
0047     } while (0)
0048 
0049 #define R1(a, b, c, d, e, f, g, h, t, w1, w2) \
0050     R(1, a, b, c, d, e, f, g, h, t, w1, w2)
0051 #define R2(a, b, c, d, e, f, g, h, t, w1, w2) \
0052     R(2, a, b, c, d, e, f, g, h, t, w1, w2)
0053 
0054 #define FF1(x, y, z)  (x ^ y ^ z)
0055 #define FF2(x, y, z)  ((x & y) | (x & z) | (y & z))
0056 
0057 #define GG1(x, y, z)  FF1(x, y, z)
0058 #define GG2(x, y, z)  ((x & y) | (~x & z))
0059 
0060 /* Message expansion */
0061 #define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17))
0062 #define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23))
0063 #define I(i)  (W[i] = get_unaligned_be32(data + i * 4))
0064 #define W1(i) (W[i & 0x0f])
0065 #define W2(i) (W[i & 0x0f] =                \
0066         P1(W[i & 0x0f]              \
0067             ^ W[(i-9) & 0x0f]       \
0068             ^ rol32(W[(i-3) & 0x0f], 15))   \
0069         ^ rol32(W[(i-13) & 0x0f], 7)        \
0070         ^ W[(i-6) & 0x0f])
0071 
0072 static void sm3_transform(struct sm3_state *sctx, u8 const *data, u32 W[16])
0073 {
0074     u32 a, b, c, d, e, f, g, h, ss1, ss2;
0075 
0076     a = sctx->state[0];
0077     b = sctx->state[1];
0078     c = sctx->state[2];
0079     d = sctx->state[3];
0080     e = sctx->state[4];
0081     f = sctx->state[5];
0082     g = sctx->state[6];
0083     h = sctx->state[7];
0084 
0085     R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
0086     R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
0087     R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
0088     R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
0089     R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
0090     R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
0091     R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
0092     R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
0093     R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
0094     R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
0095     R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
0096     R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
0097     R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
0098     R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
0099     R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
0100     R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
0101 
0102     R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
0103     R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
0104     R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
0105     R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
0106     R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
0107     R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
0108     R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
0109     R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
0110     R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
0111     R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
0112     R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
0113     R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
0114     R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
0115     R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
0116     R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
0117     R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
0118 
0119     R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
0120     R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
0121     R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
0122     R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
0123     R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
0124     R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
0125     R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
0126     R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
0127     R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
0128     R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
0129     R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
0130     R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
0131     R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
0132     R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
0133     R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
0134     R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
0135 
0136     R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
0137     R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
0138     R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
0139     R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
0140     R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
0141     R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
0142     R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
0143     R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
0144     R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
0145     R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
0146     R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
0147     R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
0148     R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
0149     R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
0150     R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
0151     R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
0152 
0153     sctx->state[0] ^= a;
0154     sctx->state[1] ^= b;
0155     sctx->state[2] ^= c;
0156     sctx->state[3] ^= d;
0157     sctx->state[4] ^= e;
0158     sctx->state[5] ^= f;
0159     sctx->state[6] ^= g;
0160     sctx->state[7] ^= h;
0161 }
0162 #undef R
0163 #undef R1
0164 #undef R2
0165 #undef I
0166 #undef W1
0167 #undef W2
0168 
0169 static inline void sm3_block(struct sm3_state *sctx,
0170         u8 const *data, int blocks, u32 W[16])
0171 {
0172     while (blocks--) {
0173         sm3_transform(sctx, data, W);
0174         data += SM3_BLOCK_SIZE;
0175     }
0176 }
0177 
0178 void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len)
0179 {
0180     unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
0181     u32 W[16];
0182 
0183     sctx->count += len;
0184 
0185     if ((partial + len) >= SM3_BLOCK_SIZE) {
0186         int blocks;
0187 
0188         if (partial) {
0189             int p = SM3_BLOCK_SIZE - partial;
0190 
0191             memcpy(sctx->buffer + partial, data, p);
0192             data += p;
0193             len -= p;
0194 
0195             sm3_block(sctx, sctx->buffer, 1, W);
0196         }
0197 
0198         blocks = len / SM3_BLOCK_SIZE;
0199         len %= SM3_BLOCK_SIZE;
0200 
0201         if (blocks) {
0202             sm3_block(sctx, data, blocks, W);
0203             data += blocks * SM3_BLOCK_SIZE;
0204         }
0205 
0206         memzero_explicit(W, sizeof(W));
0207 
0208         partial = 0;
0209     }
0210     if (len)
0211         memcpy(sctx->buffer + partial, data, len);
0212 }
0213 EXPORT_SYMBOL_GPL(sm3_update);
0214 
0215 void sm3_final(struct sm3_state *sctx, u8 *out)
0216 {
0217     const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
0218     __be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
0219     __be32 *digest = (__be32 *)out;
0220     unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
0221     u32 W[16];
0222     int i;
0223 
0224     sctx->buffer[partial++] = 0x80;
0225     if (partial > bit_offset) {
0226         memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
0227         partial = 0;
0228 
0229         sm3_block(sctx, sctx->buffer, 1, W);
0230     }
0231 
0232     memset(sctx->buffer + partial, 0, bit_offset - partial);
0233     *bits = cpu_to_be64(sctx->count << 3);
0234     sm3_block(sctx, sctx->buffer, 1, W);
0235 
0236     for (i = 0; i < 8; i++)
0237         put_unaligned_be32(sctx->state[i], digest++);
0238 
0239     /* Zeroize sensitive information. */
0240     memzero_explicit(W, sizeof(W));
0241     memzero_explicit(sctx, sizeof(*sctx));
0242 }
0243 EXPORT_SYMBOL_GPL(sm3_final);
0244 
0245 MODULE_DESCRIPTION("Generic SM3 library");
0246 MODULE_LICENSE("GPL v2");