18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Cryptographic API.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * RIPEMD-160 - RACE Integrity Primitives Evaluation Message Digest.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci#include <crypto/internal/hash.h>
128c2ecf20Sopenharmony_ci#include <linux/init.h>
138c2ecf20Sopenharmony_ci#include <linux/module.h>
148c2ecf20Sopenharmony_ci#include <linux/mm.h>
158c2ecf20Sopenharmony_ci#include <linux/types.h>
168c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "ripemd.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistruct rmd160_ctx {
218c2ecf20Sopenharmony_ci	u64 byte_count;
228c2ecf20Sopenharmony_ci	u32 state[5];
238c2ecf20Sopenharmony_ci	__le32 buffer[16];
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define K1  RMD_K1
278c2ecf20Sopenharmony_ci#define K2  RMD_K2
288c2ecf20Sopenharmony_ci#define K3  RMD_K3
298c2ecf20Sopenharmony_ci#define K4  RMD_K4
308c2ecf20Sopenharmony_ci#define K5  RMD_K5
318c2ecf20Sopenharmony_ci#define KK1 RMD_K6
328c2ecf20Sopenharmony_ci#define KK2 RMD_K7
338c2ecf20Sopenharmony_ci#define KK3 RMD_K8
348c2ecf20Sopenharmony_ci#define KK4 RMD_K9
358c2ecf20Sopenharmony_ci#define KK5 RMD_K1
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define F1(x, y, z) (x ^ y ^ z)		/* XOR */
388c2ecf20Sopenharmony_ci#define F2(x, y, z) (z ^ (x & (y ^ z)))	/* x ? y : z */
398c2ecf20Sopenharmony_ci#define F3(x, y, z) ((x | ~y) ^ z)
408c2ecf20Sopenharmony_ci#define F4(x, y, z) (y ^ (z & (x ^ y)))	/* z ? x : y */
418c2ecf20Sopenharmony_ci#define F5(x, y, z) (x ^ (y | ~z))
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define ROUND(a, b, c, d, e, f, k, x, s)  { \
448c2ecf20Sopenharmony_ci	(a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \
458c2ecf20Sopenharmony_ci	(a) = rol32((a), (s)) + (e); \
468c2ecf20Sopenharmony_ci	(c) = rol32((c), 10); \
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic void rmd160_transform(u32 *state, const __le32 *in)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	/* Initialize left lane */
548c2ecf20Sopenharmony_ci	aa = state[0];
558c2ecf20Sopenharmony_ci	bb = state[1];
568c2ecf20Sopenharmony_ci	cc = state[2];
578c2ecf20Sopenharmony_ci	dd = state[3];
588c2ecf20Sopenharmony_ci	ee = state[4];
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	/* Initialize right lane */
618c2ecf20Sopenharmony_ci	aaa = state[0];
628c2ecf20Sopenharmony_ci	bbb = state[1];
638c2ecf20Sopenharmony_ci	ccc = state[2];
648c2ecf20Sopenharmony_ci	ddd = state[3];
658c2ecf20Sopenharmony_ci	eee = state[4];
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	/* round 1: left lane */
688c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[0],  11);
698c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[1],  14);
708c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[2],  15);
718c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[3],  12);
728c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[4],   5);
738c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[5],   8);
748c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[6],   7);
758c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[7],   9);
768c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[8],  11);
778c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[9],  13);
788c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[10], 14);
798c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F1, K1, in[11], 15);
808c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F1, K1, in[12],  6);
818c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F1, K1, in[13],  7);
828c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F1, K1, in[14],  9);
838c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F1, K1, in[15],  8);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/* round 2: left lane" */
868c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[7],   7);
878c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[4],   6);
888c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[13],  8);
898c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[1],  13);
908c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[10], 11);
918c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[6],   9);
928c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[15],  7);
938c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[3],  15);
948c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[12],  7);
958c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[0],  12);
968c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[9],  15);
978c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F2, K2, in[5],   9);
988c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F2, K2, in[2],  11);
998c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F2, K2, in[14],  7);
1008c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F2, K2, in[11], 13);
1018c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F2, K2, in[8],  12);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	/* round 3: left lane" */
1048c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[3],  11);
1058c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[10], 13);
1068c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[14],  6);
1078c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[4],   7);
1088c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[9],  14);
1098c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[15],  9);
1108c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[8],  13);
1118c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[1],  15);
1128c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[2],  14);
1138c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[7],   8);
1148c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[0],  13);
1158c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F3, K3, in[6],   6);
1168c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F3, K3, in[13],  5);
1178c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F3, K3, in[11], 12);
1188c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F3, K3, in[5],   7);
1198c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F3, K3, in[12],  5);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/* round 4: left lane" */
1228c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[1],  11);
1238c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[9],  12);
1248c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[11], 14);
1258c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[10], 15);
1268c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[0],  14);
1278c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[8],  15);
1288c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[12],  9);
1298c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[4],   8);
1308c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[13],  9);
1318c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[3],  14);
1328c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[7],   5);
1338c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F4, K4, in[15],  6);
1348c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F4, K4, in[14],  8);
1358c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F4, K4, in[5],   6);
1368c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F4, K4, in[6],   5);
1378c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F4, K4, in[2],  12);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	/* round 5: left lane" */
1408c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[4],   9);
1418c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[0],  15);
1428c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[5],   5);
1438c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[9],  11);
1448c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[7],   6);
1458c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[12],  8);
1468c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[2],  13);
1478c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[10], 12);
1488c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[14],  5);
1498c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[1],  12);
1508c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[3],  13);
1518c2ecf20Sopenharmony_ci	ROUND(aa, bb, cc, dd, ee, F5, K5, in[8],  14);
1528c2ecf20Sopenharmony_ci	ROUND(ee, aa, bb, cc, dd, F5, K5, in[11], 11);
1538c2ecf20Sopenharmony_ci	ROUND(dd, ee, aa, bb, cc, F5, K5, in[6],   8);
1548c2ecf20Sopenharmony_ci	ROUND(cc, dd, ee, aa, bb, F5, K5, in[15],  5);
1558c2ecf20Sopenharmony_ci	ROUND(bb, cc, dd, ee, aa, F5, K5, in[13],  6);
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	/* round 1: right lane */
1588c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[5],   8);
1598c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[14],  9);
1608c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[7],   9);
1618c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[0],  11);
1628c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[9],  13);
1638c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[2],  15);
1648c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[11], 15);
1658c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[4],   5);
1668c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[13],  7);
1678c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[6],   7);
1688c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[15],  8);
1698c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[8],  11);
1708c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[1],  14);
1718c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[10], 14);
1728c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[3],  12);
1738c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[12],  6);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	/* round 2: right lane */
1768c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[6],   9);
1778c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[11], 13);
1788c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[3],  15);
1798c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[7],   7);
1808c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[0],  12);
1818c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[13],  8);
1828c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[5],   9);
1838c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[10], 11);
1848c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[14],  7);
1858c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[15],  7);
1868c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[8],  12);
1878c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[12],  7);
1888c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[4],   6);
1898c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[9],  15);
1908c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[1],  13);
1918c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[2],  11);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	/* round 3: right lane */
1948c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[15],  9);
1958c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[5],   7);
1968c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[1],  15);
1978c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[3],  11);
1988c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[7],   8);
1998c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[14],  6);
2008c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[6],   6);
2018c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[9],  14);
2028c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[11], 12);
2038c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[8],  13);
2048c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[12],  5);
2058c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[2],  14);
2068c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[10], 13);
2078c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[0],  13);
2088c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[4],   7);
2098c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[13],  5);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	/* round 4: right lane */
2128c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[8],  15);
2138c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[6],   5);
2148c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[4],   8);
2158c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[1],  11);
2168c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[3],  14);
2178c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[11], 14);
2188c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[15],  6);
2198c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[0],  14);
2208c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[5],   6);
2218c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[12],  9);
2228c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[2],  12);
2238c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[13],  9);
2248c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[9],  12);
2258c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[7],   5);
2268c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[10], 15);
2278c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[14],  8);
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	/* round 5: right lane */
2308c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[12],  8);
2318c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[15],  5);
2328c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[10], 12);
2338c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[4],   9);
2348c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[1],  12);
2358c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[5],   5);
2368c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[8],  14);
2378c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[7],   6);
2388c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[6],   8);
2398c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[2],  13);
2408c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[13],  6);
2418c2ecf20Sopenharmony_ci	ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[14],  5);
2428c2ecf20Sopenharmony_ci	ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[0],  15);
2438c2ecf20Sopenharmony_ci	ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[3],  13);
2448c2ecf20Sopenharmony_ci	ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[9],  11);
2458c2ecf20Sopenharmony_ci	ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[11], 11);
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	/* combine results */
2488c2ecf20Sopenharmony_ci	ddd += cc + state[1];		/* final result for state[0] */
2498c2ecf20Sopenharmony_ci	state[1] = state[2] + dd + eee;
2508c2ecf20Sopenharmony_ci	state[2] = state[3] + ee + aaa;
2518c2ecf20Sopenharmony_ci	state[3] = state[4] + aa + bbb;
2528c2ecf20Sopenharmony_ci	state[4] = state[0] + bb + ccc;
2538c2ecf20Sopenharmony_ci	state[0] = ddd;
2548c2ecf20Sopenharmony_ci}
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cistatic int rmd160_init(struct shash_desc *desc)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	rctx->byte_count = 0;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	rctx->state[0] = RMD_H0;
2638c2ecf20Sopenharmony_ci	rctx->state[1] = RMD_H1;
2648c2ecf20Sopenharmony_ci	rctx->state[2] = RMD_H2;
2658c2ecf20Sopenharmony_ci	rctx->state[3] = RMD_H3;
2668c2ecf20Sopenharmony_ci	rctx->state[4] = RMD_H4;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	memset(rctx->buffer, 0, sizeof(rctx->buffer));
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	return 0;
2718c2ecf20Sopenharmony_ci}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_cistatic int rmd160_update(struct shash_desc *desc, const u8 *data,
2748c2ecf20Sopenharmony_ci			 unsigned int len)
2758c2ecf20Sopenharmony_ci{
2768c2ecf20Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
2778c2ecf20Sopenharmony_ci	const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	rctx->byte_count += len;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	/* Enough space in buffer? If so copy and we're done */
2828c2ecf20Sopenharmony_ci	if (avail > len) {
2838c2ecf20Sopenharmony_ci		memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
2848c2ecf20Sopenharmony_ci		       data, len);
2858c2ecf20Sopenharmony_ci		goto out;
2868c2ecf20Sopenharmony_ci	}
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
2898c2ecf20Sopenharmony_ci	       data, avail);
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	rmd160_transform(rctx->state, rctx->buffer);
2928c2ecf20Sopenharmony_ci	data += avail;
2938c2ecf20Sopenharmony_ci	len -= avail;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	while (len >= sizeof(rctx->buffer)) {
2968c2ecf20Sopenharmony_ci		memcpy(rctx->buffer, data, sizeof(rctx->buffer));
2978c2ecf20Sopenharmony_ci		rmd160_transform(rctx->state, rctx->buffer);
2988c2ecf20Sopenharmony_ci		data += sizeof(rctx->buffer);
2998c2ecf20Sopenharmony_ci		len -= sizeof(rctx->buffer);
3008c2ecf20Sopenharmony_ci	}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci	memcpy(rctx->buffer, data, len);
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ciout:
3058c2ecf20Sopenharmony_ci	return 0;
3068c2ecf20Sopenharmony_ci}
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci/* Add padding and return the message digest. */
3098c2ecf20Sopenharmony_cistatic int rmd160_final(struct shash_desc *desc, u8 *out)
3108c2ecf20Sopenharmony_ci{
3118c2ecf20Sopenharmony_ci	struct rmd160_ctx *rctx = shash_desc_ctx(desc);
3128c2ecf20Sopenharmony_ci	u32 i, index, padlen;
3138c2ecf20Sopenharmony_ci	__le64 bits;
3148c2ecf20Sopenharmony_ci	__le32 *dst = (__le32 *)out;
3158c2ecf20Sopenharmony_ci	static const u8 padding[64] = { 0x80, };
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	bits = cpu_to_le64(rctx->byte_count << 3);
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	/* Pad out to 56 mod 64 */
3208c2ecf20Sopenharmony_ci	index = rctx->byte_count & 0x3f;
3218c2ecf20Sopenharmony_ci	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
3228c2ecf20Sopenharmony_ci	rmd160_update(desc, padding, padlen);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	/* Append length */
3258c2ecf20Sopenharmony_ci	rmd160_update(desc, (const u8 *)&bits, sizeof(bits));
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	/* Store state in digest */
3288c2ecf20Sopenharmony_ci	for (i = 0; i < 5; i++)
3298c2ecf20Sopenharmony_ci		dst[i] = cpu_to_le32p(&rctx->state[i]);
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	/* Wipe context */
3328c2ecf20Sopenharmony_ci	memset(rctx, 0, sizeof(*rctx));
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	return 0;
3358c2ecf20Sopenharmony_ci}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_cistatic struct shash_alg alg = {
3388c2ecf20Sopenharmony_ci	.digestsize	=	RMD160_DIGEST_SIZE,
3398c2ecf20Sopenharmony_ci	.init		=	rmd160_init,
3408c2ecf20Sopenharmony_ci	.update		=	rmd160_update,
3418c2ecf20Sopenharmony_ci	.final		=	rmd160_final,
3428c2ecf20Sopenharmony_ci	.descsize	=	sizeof(struct rmd160_ctx),
3438c2ecf20Sopenharmony_ci	.base		=	{
3448c2ecf20Sopenharmony_ci		.cra_name	 =	"rmd160",
3458c2ecf20Sopenharmony_ci		.cra_driver_name =	"rmd160-generic",
3468c2ecf20Sopenharmony_ci		.cra_blocksize	 =	RMD160_BLOCK_SIZE,
3478c2ecf20Sopenharmony_ci		.cra_module	 =	THIS_MODULE,
3488c2ecf20Sopenharmony_ci	}
3498c2ecf20Sopenharmony_ci};
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cistatic int __init rmd160_mod_init(void)
3528c2ecf20Sopenharmony_ci{
3538c2ecf20Sopenharmony_ci	return crypto_register_shash(&alg);
3548c2ecf20Sopenharmony_ci}
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cistatic void __exit rmd160_mod_fini(void)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	crypto_unregister_shash(&alg);
3598c2ecf20Sopenharmony_ci}
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_cisubsys_initcall(rmd160_mod_init);
3628c2ecf20Sopenharmony_cimodule_exit(rmd160_mod_fini);
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
3658c2ecf20Sopenharmony_ciMODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
3668c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("RIPEMD-160 Message Digest");
3678c2ecf20Sopenharmony_ciMODULE_ALIAS_CRYPTO("rmd160");
368