162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Cryptographic API.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * RIPEMD-160 - RACE Integrity Primitives Evaluation Message Digest.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#include <crypto/internal/hash.h>
1262306a36Sopenharmony_ci#include <linux/init.h>
1362306a36Sopenharmony_ci#include <linux/module.h>
1462306a36Sopenharmony_ci#include <linux/mm.h>
1562306a36Sopenharmony_ci#include <linux/types.h>
1662306a36Sopenharmony_ci#include <asm/byteorder.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "ripemd.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistruct rmd160_ctx {
2162306a36Sopenharmony_ci	u64 byte_count;
2262306a36Sopenharmony_ci	u32 state[5];
2362306a36Sopenharmony_ci	__le32 buffer[16];
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define K1  RMD_K1
2762306a36Sopenharmony_ci#define K2  RMD_K2
2862306a36Sopenharmony_ci#define K3  RMD_K3
2962306a36Sopenharmony_ci#define K4  RMD_K4
3062306a36Sopenharmony_ci#define K5  RMD_K5
3162306a36Sopenharmony_ci#define KK1 RMD_K6
3262306a36Sopenharmony_ci#define KK2 RMD_K7
3362306a36Sopenharmony_ci#define KK3 RMD_K8
3462306a36Sopenharmony_ci#define KK4 RMD_K9
3562306a36Sopenharmony_ci#define KK5 RMD_K1
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define F1(x, y, z) (x ^ y ^ z)		/* XOR */
3862306a36Sopenharmony_ci#define F2(x, y, z) (z ^ (x & (y ^ z)))	/* x ? y : z */
3962306a36Sopenharmony_ci#define F3(x, y, z) ((x | ~y) ^ z)
4062306a36Sopenharmony_ci#define F4(x, y, z) (y ^ (z & (x ^ y)))	/* z ? x : y */
4162306a36Sopenharmony_ci#define F5(x, y, z) (x ^ (y | ~z))
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define ROUND(a, b, c, d, e, f, k, x, s)  { \
4462306a36Sopenharmony_ci	(a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \
4562306a36Sopenharmony_ci	(a) = rol32((a), (s)) + (e); \
4662306a36Sopenharmony_ci	(c) = rol32((c), 10); \
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic void rmd160_transform(u32 *state, const __le32 *in)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/* Initialize left lane */
5462306a36Sopenharmony_ci	aa = state[0];
5562306a36Sopenharmony_ci	bb = state[1];
5662306a36Sopenharmony_ci	cc = state[2];
5762306a36Sopenharmony_ci	dd = state[3];
5862306a36Sopenharmony_ci	ee = state[4];
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	/* Initialize right lane */
6162306a36Sopenharmony_ci	aaa = state[0];
6262306a36Sopenharmony_ci	bbb = state[1];
6362306a36Sopenharmony_ci	ccc = state[2];
6462306a36Sopenharmony_ci	ddd = state[3];
6562306a36Sopenharmony_ci	eee = state[4];
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	/* round 1: left lane */
6862306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[0],  11);
6962306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[1],  14);
7062306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[2],  15);
7162306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[3],  12);
7262306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[4],   5);
7362306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[5],   8);
7462306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[6],   7);
7562306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[7],   9);
7662306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[8],  11);
7762306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[9],  13);
7862306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[10], 14);
7962306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[11], 15);
8062306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[12],  6);
8162306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[13],  7);
8262306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[14],  9);
8362306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[15],  8);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	/* round 2: left lane" */
8662306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[7],   7);
8762306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[4],   6);
8862306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[13],  8);
8962306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[1],  13);
9062306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[10], 11);
9162306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[6],   9);
9262306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[15],  7);
9362306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[3],  15);
9462306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[12],  7);
9562306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[0],  12);
9662306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[9],  15);
9762306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[5],   9);
9862306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[2],  11);
9962306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[14],  7);
10062306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[11], 13);
10162306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[8],  12);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	/* round 3: left lane" */
10462306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[3],  11);
10562306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[10], 13);
10662306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[14],  6);
10762306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[4],   7);
10862306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[9],  14);
10962306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[15],  9);
11062306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[8],  13);
11162306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[1],  15);
11262306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[2],  14);
11362306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[7],   8);
11462306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[0],  13);
11562306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[6],   6);
11662306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[13],  5);
11762306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[11], 12);
11862306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[5],   7);
11962306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[12],  5);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	/* round 4: left lane" */
12262306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[1],  11);
12362306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[9],  12);
12462306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[11], 14);
12562306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[10], 15);
12662306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[0],  14);
12762306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[8],  15);
12862306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[12],  9);
12962306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[4],   8);
13062306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[13],  9);
13162306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[3],  14);
13262306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[7],   5);
13362306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[15],  6);
13462306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[14],  8);
13562306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[5],   6);
13662306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[6],   5);
13762306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[2],  12);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	/* round 5: left lane" */
14062306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[4],   9);
14162306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[0],  15);
14262306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[5],   5);
14362306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[9],  11);
14462306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[7],   6);
14562306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[12],  8);
14662306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[2],  13);
14762306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[10], 12);
14862306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[14],  5);
14962306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[1],  12);
15062306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[3],  13);
15162306a36Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[8],  14);
15262306a36Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[11], 11);
15362306a36Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[6],   8);
15462306a36Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[15],  5);
15562306a36Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[13],  6);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* round 1: right lane */
15862306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[5],   8);
15962306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[14],  9);
16062306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[7],   9);
16162306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[0],  11);
16262306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[9],  13);
16362306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[2],  15);
16462306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[11], 15);
16562306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[4],   5);
16662306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[13],  7);
16762306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[6],   7);
16862306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[15],  8);
16962306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[8],  11);
17062306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[1],  14);
17162306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[10], 14);
17262306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[3],  12);
17362306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[12],  6);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	/* round 2: right lane */
17662306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[6],   9);
17762306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[11], 13);
17862306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[3],  15);
17962306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[7],   7);
18062306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[0],  12);
18162306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[13],  8);
18262306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[5],   9);
18362306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[10], 11);
18462306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[14],  7);
18562306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[15],  7);
18662306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[8],  12);
18762306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[12],  7);
18862306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[4],   6);
18962306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[9],  15);
19062306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[1],  13);
19162306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[2],  11);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/* round 3: right lane */
19462306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[15],  9);
19562306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[5],   7);
19662306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[1],  15);
19762306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[3],  11);
19862306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[7],   8);
19962306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[14],  6);
20062306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[6],   6);
20162306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[9],  14);
20262306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[11], 12);
20362306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[8],  13);
20462306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[12],  5);
20562306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[2],  14);
20662306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[10], 13);
20762306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[0],  13);
20862306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[4],   7);
20962306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[13],  5);
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	/* round 4: right lane */
21262306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[8],  15);
21362306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[6],   5);
21462306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[4],   8);
21562306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[1],  11);
21662306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[3],  14);
21762306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[11], 14);
21862306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[15],  6);
21962306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[0],  14);
22062306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[5],   6);
22162306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[12],  9);
22262306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[2],  12);
22362306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[13],  9);
22462306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[9],  12);
22562306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[7],   5);
22662306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[10], 15);
22762306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[14],  8);
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	/* round 5: right lane */
23062306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[12],  8);
23162306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[15],  5);
23262306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[10], 12);
23362306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[4],   9);
23462306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[1],  12);
23562306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[5],   5);
23662306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[8],  14);
23762306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[7],   6);
23862306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[6],   8);
23962306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[2],  13);
24062306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[13],  6);
24162306a36Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[14],  5);
24262306a36Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[0],  15);
24362306a36Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[3],  13);
24462306a36Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[9],  11);
24562306a36Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[11], 11);
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	/* combine results */
24862306a36Sopenharmony_ci	ddd += cc + state[1];		/* final result for state[0] */
24962306a36Sopenharmony_ci	state[1] = state[2] + dd + eee;
25062306a36Sopenharmony_ci	state[2] = state[3] + ee + aaa;
25162306a36Sopenharmony_ci	state[3] = state[4] + aa + bbb;
25262306a36Sopenharmony_ci	state[4] = state[0] + bb + ccc;
25362306a36Sopenharmony_ci	state[0] = ddd;
25462306a36Sopenharmony_ci}
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic int rmd160_init(struct shash_desc *desc)
25762306a36Sopenharmony_ci{
25862306a36Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	rctx->byte_count = 0;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	rctx->state[0] = RMD_H0;
26362306a36Sopenharmony_ci	rctx->state[1] = RMD_H1;
26462306a36Sopenharmony_ci	rctx->state[2] = RMD_H2;
26562306a36Sopenharmony_ci	rctx->state[3] = RMD_H3;
26662306a36Sopenharmony_ci	rctx->state[4] = RMD_H4;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	memset(rctx->buffer, 0, sizeof(rctx->buffer));
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	return 0;
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_cistatic int rmd160_update(struct shash_desc *desc, const u8 *data,
27462306a36Sopenharmony_ci			 unsigned int len)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
27762306a36Sopenharmony_ci	const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	rctx->byte_count += len;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	/* Enough space in buffer? If so copy and we're done */
28262306a36Sopenharmony_ci	if (avail > len) {
28362306a36Sopenharmony_ci		memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
28462306a36Sopenharmony_ci		       data, len);
28562306a36Sopenharmony_ci		goto out;
28662306a36Sopenharmony_ci	}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
28962306a36Sopenharmony_ci	       data, avail);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	rmd160_transform(rctx->state, rctx->buffer);
29262306a36Sopenharmony_ci	data += avail;
29362306a36Sopenharmony_ci	len -= avail;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	while (len >= sizeof(rctx->buffer)) {
29662306a36Sopenharmony_ci		memcpy(rctx->buffer, data, sizeof(rctx->buffer));
29762306a36Sopenharmony_ci		rmd160_transform(rctx->state, rctx->buffer);
29862306a36Sopenharmony_ci		data += sizeof(rctx->buffer);
29962306a36Sopenharmony_ci		len -= sizeof(rctx->buffer);
30062306a36Sopenharmony_ci	}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	memcpy(rctx->buffer, data, len);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ciout:
30562306a36Sopenharmony_ci	return 0;
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci/* Add padding and return the message digest. */
30962306a36Sopenharmony_cistatic int rmd160_final(struct shash_desc *desc, u8 *out)
31062306a36Sopenharmony_ci{
31162306a36Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
31262306a36Sopenharmony_ci	u32 i, index, padlen;
31362306a36Sopenharmony_ci	__le64 bits;
31462306a36Sopenharmony_ci	__le32 *dst = (__le32 *)out;
31562306a36Sopenharmony_ci	static const u8 padding[64] = { 0x80, };
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	bits = cpu_to_le64(rctx->byte_count << 3);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/* Pad out to 56 mod 64 */
32062306a36Sopenharmony_ci	index = rctx->byte_count & 0x3f;
32162306a36Sopenharmony_ci	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
32262306a36Sopenharmony_ci	rmd160_update(desc, padding, padlen);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	/* Append length */
32562306a36Sopenharmony_ci	rmd160_update(desc, (const u8 *)&bits, sizeof(bits));
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	/* Store state in digest */
32862306a36Sopenharmony_ci	for (i = 0; i < 5; i++)
32962306a36Sopenharmony_ci		dst[i] = cpu_to_le32p(&rctx->state[i]);
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	/* Wipe context */
33262306a36Sopenharmony_ci	memset(rctx, 0, sizeof(*rctx));
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	return 0;
33562306a36Sopenharmony_ci}
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic struct shash_alg alg = {
33862306a36Sopenharmony_ci	.digestsize	=	RMD160_DIGEST_SIZE,
33962306a36Sopenharmony_ci	.init		=	rmd160_init,
34062306a36Sopenharmony_ci	.update		=	rmd160_update,
34162306a36Sopenharmony_ci	.final		=	rmd160_final,
34262306a36Sopenharmony_ci	.descsize	=	sizeof(struct rmd160_ctx),
34362306a36Sopenharmony_ci	.base		=	{
34462306a36Sopenharmony_ci		.cra_name	 =	"rmd160",
34562306a36Sopenharmony_ci		.cra_driver_name =	"rmd160-generic",
34662306a36Sopenharmony_ci		.cra_blocksize	 =	RMD160_BLOCK_SIZE,
34762306a36Sopenharmony_ci		.cra_module	 =	THIS_MODULE,
34862306a36Sopenharmony_ci	}
34962306a36Sopenharmony_ci};
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic int __init rmd160_mod_init(void)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	return crypto_register_shash(&alg);
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic void __exit rmd160_mod_fini(void)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	crypto_unregister_shash(&alg);
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cisubsys_initcall(rmd160_mod_init);
36262306a36Sopenharmony_cimodule_exit(rmd160_mod_fini);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ciMODULE_LICENSE("GPL");
36562306a36Sopenharmony_ciMODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
36662306a36Sopenharmony_ciMODULE_DESCRIPTION("RIPEMD-160 Message Digest");
36762306a36Sopenharmony_ciMODULE_ALIAS_CRYPTO("rmd160");
368