xref: /optee_os/core/lib/libtomcrypt/src/hashes/rmd320.c (revision 8411e6ad673d20c4742ed30c785e3f5cdea54dfa)
1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier #include "tomcrypt_private.h"
45a913ee7SJerome Forissier 
55a913ee7SJerome Forissier /**
65a913ee7SJerome Forissier    @file rmd320.c
75a913ee7SJerome Forissier    RMD320 hash function
85a913ee7SJerome Forissier */
95a913ee7SJerome Forissier 
105a913ee7SJerome Forissier #ifdef LTC_RIPEMD320
115a913ee7SJerome Forissier 
125a913ee7SJerome Forissier const struct ltc_hash_descriptor rmd320_desc =
135a913ee7SJerome Forissier {
145a913ee7SJerome Forissier     "rmd320",
155a913ee7SJerome Forissier     14,
165a913ee7SJerome Forissier     40,
175a913ee7SJerome Forissier     64,
185a913ee7SJerome Forissier 
195a913ee7SJerome Forissier     /* OID ... does not exist
205a913ee7SJerome Forissier      * http://oid-info.com/get/1.3.36.3.2 */
215a913ee7SJerome Forissier    { 0 },
225a913ee7SJerome Forissier    0,
235a913ee7SJerome Forissier 
245a913ee7SJerome Forissier     &rmd320_init,
255a913ee7SJerome Forissier     &rmd320_process,
265a913ee7SJerome Forissier     &rmd320_done,
275a913ee7SJerome Forissier     &rmd320_test,
285a913ee7SJerome Forissier     NULL
295a913ee7SJerome Forissier };
305a913ee7SJerome Forissier 
315a913ee7SJerome Forissier /* the five basic functions F(), G() and H() */
325a913ee7SJerome Forissier #define F(x, y, z)        ((x) ^ (y) ^ (z))
335a913ee7SJerome Forissier #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
345a913ee7SJerome Forissier #define H(x, y, z)        (((x) | ~(y)) ^ (z))
355a913ee7SJerome Forissier #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
365a913ee7SJerome Forissier #define J(x, y, z)        ((x) ^ ((y) | ~(z)))
375a913ee7SJerome Forissier 
385a913ee7SJerome Forissier /* the ten basic operations FF() through III() */
395a913ee7SJerome Forissier #define FF(a, b, c, d, e, x, s)        \
405a913ee7SJerome Forissier       (a) += F((b), (c), (d)) + (x);\
415a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
425a913ee7SJerome Forissier       (c) = ROLc((c), 10);
435a913ee7SJerome Forissier 
445a913ee7SJerome Forissier #define GG(a, b, c, d, e, x, s)        \
455a913ee7SJerome Forissier       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
465a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
475a913ee7SJerome Forissier       (c) = ROLc((c), 10);
485a913ee7SJerome Forissier 
495a913ee7SJerome Forissier #define HH(a, b, c, d, e, x, s)        \
505a913ee7SJerome Forissier       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
515a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
525a913ee7SJerome Forissier       (c) = ROLc((c), 10);
535a913ee7SJerome Forissier 
545a913ee7SJerome Forissier #define II(a, b, c, d, e, x, s)        \
555a913ee7SJerome Forissier       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
565a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
575a913ee7SJerome Forissier       (c) = ROLc((c), 10);
585a913ee7SJerome Forissier 
595a913ee7SJerome Forissier #define JJ(a, b, c, d, e, x, s)        \
605a913ee7SJerome Forissier       (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
615a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
625a913ee7SJerome Forissier       (c) = ROLc((c), 10);
635a913ee7SJerome Forissier 
645a913ee7SJerome Forissier #define FFF(a, b, c, d, e, x, s)        \
655a913ee7SJerome Forissier       (a) += F((b), (c), (d)) + (x);\
665a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
675a913ee7SJerome Forissier       (c) = ROLc((c), 10);
685a913ee7SJerome Forissier 
695a913ee7SJerome Forissier #define GGG(a, b, c, d, e, x, s)        \
705a913ee7SJerome Forissier       (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
715a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
725a913ee7SJerome Forissier       (c) = ROLc((c), 10);
735a913ee7SJerome Forissier 
745a913ee7SJerome Forissier #define HHH(a, b, c, d, e, x, s)        \
755a913ee7SJerome Forissier       (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
765a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
775a913ee7SJerome Forissier       (c) = ROLc((c), 10);
785a913ee7SJerome Forissier 
795a913ee7SJerome Forissier #define III(a, b, c, d, e, x, s)        \
805a913ee7SJerome Forissier       (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
815a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
825a913ee7SJerome Forissier       (c) = ROLc((c), 10);
835a913ee7SJerome Forissier 
845a913ee7SJerome Forissier #define JJJ(a, b, c, d, e, x, s)        \
855a913ee7SJerome Forissier       (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
865a913ee7SJerome Forissier       (a) = ROLc((a), (s)) + (e);\
875a913ee7SJerome Forissier       (c) = ROLc((c), 10);
885a913ee7SJerome Forissier 
895a913ee7SJerome Forissier 
905a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
ss_rmd320_compress(hash_state * md,const unsigned char * buf)91*8411e6adSJerome Forissier static int ss_rmd320_compress(hash_state *md, const unsigned char *buf)
925a913ee7SJerome Forissier #else
93*8411e6adSJerome Forissier static int  s_rmd320_compress(hash_state *md, const unsigned char *buf)
945a913ee7SJerome Forissier #endif
955a913ee7SJerome Forissier {
965a913ee7SJerome Forissier    ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
975a913ee7SJerome Forissier    int i;
985a913ee7SJerome Forissier 
995a913ee7SJerome Forissier    /* load words X */
1005a913ee7SJerome Forissier    for (i = 0; i < 16; i++){
1015a913ee7SJerome Forissier       LOAD32L(X[i], buf + (4 * i));
1025a913ee7SJerome Forissier    }
1035a913ee7SJerome Forissier 
1045a913ee7SJerome Forissier    /* load state */
1055a913ee7SJerome Forissier    aa = md->rmd320.state[0];
1065a913ee7SJerome Forissier    bb = md->rmd320.state[1];
1075a913ee7SJerome Forissier    cc = md->rmd320.state[2];
1085a913ee7SJerome Forissier    dd = md->rmd320.state[3];
1095a913ee7SJerome Forissier    ee = md->rmd320.state[4];
1105a913ee7SJerome Forissier    aaa = md->rmd320.state[5];
1115a913ee7SJerome Forissier    bbb = md->rmd320.state[6];
1125a913ee7SJerome Forissier    ccc = md->rmd320.state[7];
1135a913ee7SJerome Forissier    ddd = md->rmd320.state[8];
1145a913ee7SJerome Forissier    eee = md->rmd320.state[9];
1155a913ee7SJerome Forissier 
1165a913ee7SJerome Forissier    /* round 1 */
1175a913ee7SJerome Forissier    FF(aa, bb, cc, dd, ee, X[ 0], 11);
1185a913ee7SJerome Forissier    FF(ee, aa, bb, cc, dd, X[ 1], 14);
1195a913ee7SJerome Forissier    FF(dd, ee, aa, bb, cc, X[ 2], 15);
1205a913ee7SJerome Forissier    FF(cc, dd, ee, aa, bb, X[ 3], 12);
1215a913ee7SJerome Forissier    FF(bb, cc, dd, ee, aa, X[ 4],  5);
1225a913ee7SJerome Forissier    FF(aa, bb, cc, dd, ee, X[ 5],  8);
1235a913ee7SJerome Forissier    FF(ee, aa, bb, cc, dd, X[ 6],  7);
1245a913ee7SJerome Forissier    FF(dd, ee, aa, bb, cc, X[ 7],  9);
1255a913ee7SJerome Forissier    FF(cc, dd, ee, aa, bb, X[ 8], 11);
1265a913ee7SJerome Forissier    FF(bb, cc, dd, ee, aa, X[ 9], 13);
1275a913ee7SJerome Forissier    FF(aa, bb, cc, dd, ee, X[10], 14);
1285a913ee7SJerome Forissier    FF(ee, aa, bb, cc, dd, X[11], 15);
1295a913ee7SJerome Forissier    FF(dd, ee, aa, bb, cc, X[12],  6);
1305a913ee7SJerome Forissier    FF(cc, dd, ee, aa, bb, X[13],  7);
1315a913ee7SJerome Forissier    FF(bb, cc, dd, ee, aa, X[14],  9);
1325a913ee7SJerome Forissier    FF(aa, bb, cc, dd, ee, X[15],  8);
1335a913ee7SJerome Forissier 
1345a913ee7SJerome Forissier    /* parallel round 1 */
1355a913ee7SJerome Forissier    JJJ(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
1365a913ee7SJerome Forissier    JJJ(eee, aaa, bbb, ccc, ddd, X[14],  9);
1375a913ee7SJerome Forissier    JJJ(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
1385a913ee7SJerome Forissier    JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
1395a913ee7SJerome Forissier    JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
1405a913ee7SJerome Forissier    JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
1415a913ee7SJerome Forissier    JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
1425a913ee7SJerome Forissier    JJJ(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
1435a913ee7SJerome Forissier    JJJ(ccc, ddd, eee, aaa, bbb, X[13],  7);
1445a913ee7SJerome Forissier    JJJ(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
1455a913ee7SJerome Forissier    JJJ(aaa, bbb, ccc, ddd, eee, X[15],  8);
1465a913ee7SJerome Forissier    JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
1475a913ee7SJerome Forissier    JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
1485a913ee7SJerome Forissier    JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
1495a913ee7SJerome Forissier    JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
1505a913ee7SJerome Forissier    JJJ(aaa, bbb, ccc, ddd, eee, X[12],  6);
1515a913ee7SJerome Forissier 
1525a913ee7SJerome Forissier    tmp = aa; aa = aaa; aaa = tmp;
1535a913ee7SJerome Forissier 
1545a913ee7SJerome Forissier    /* round 2 */
1555a913ee7SJerome Forissier    GG(ee, aa, bb, cc, dd, X[ 7],  7);
1565a913ee7SJerome Forissier    GG(dd, ee, aa, bb, cc, X[ 4],  6);
1575a913ee7SJerome Forissier    GG(cc, dd, ee, aa, bb, X[13],  8);
1585a913ee7SJerome Forissier    GG(bb, cc, dd, ee, aa, X[ 1], 13);
1595a913ee7SJerome Forissier    GG(aa, bb, cc, dd, ee, X[10], 11);
1605a913ee7SJerome Forissier    GG(ee, aa, bb, cc, dd, X[ 6],  9);
1615a913ee7SJerome Forissier    GG(dd, ee, aa, bb, cc, X[15],  7);
1625a913ee7SJerome Forissier    GG(cc, dd, ee, aa, bb, X[ 3], 15);
1635a913ee7SJerome Forissier    GG(bb, cc, dd, ee, aa, X[12],  7);
1645a913ee7SJerome Forissier    GG(aa, bb, cc, dd, ee, X[ 0], 12);
1655a913ee7SJerome Forissier    GG(ee, aa, bb, cc, dd, X[ 9], 15);
1665a913ee7SJerome Forissier    GG(dd, ee, aa, bb, cc, X[ 5],  9);
1675a913ee7SJerome Forissier    GG(cc, dd, ee, aa, bb, X[ 2], 11);
1685a913ee7SJerome Forissier    GG(bb, cc, dd, ee, aa, X[14],  7);
1695a913ee7SJerome Forissier    GG(aa, bb, cc, dd, ee, X[11], 13);
1705a913ee7SJerome Forissier    GG(ee, aa, bb, cc, dd, X[ 8], 12);
1715a913ee7SJerome Forissier 
1725a913ee7SJerome Forissier    /* parallel round 2 */
1735a913ee7SJerome Forissier    III(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
1745a913ee7SJerome Forissier    III(ddd, eee, aaa, bbb, ccc, X[11], 13);
1755a913ee7SJerome Forissier    III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
1765a913ee7SJerome Forissier    III(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
1775a913ee7SJerome Forissier    III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
1785a913ee7SJerome Forissier    III(eee, aaa, bbb, ccc, ddd, X[13],  8);
1795a913ee7SJerome Forissier    III(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
1805a913ee7SJerome Forissier    III(ccc, ddd, eee, aaa, bbb, X[10], 11);
1815a913ee7SJerome Forissier    III(bbb, ccc, ddd, eee, aaa, X[14],  7);
1825a913ee7SJerome Forissier    III(aaa, bbb, ccc, ddd, eee, X[15],  7);
1835a913ee7SJerome Forissier    III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
1845a913ee7SJerome Forissier    III(ddd, eee, aaa, bbb, ccc, X[12],  7);
1855a913ee7SJerome Forissier    III(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
1865a913ee7SJerome Forissier    III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
1875a913ee7SJerome Forissier    III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
1885a913ee7SJerome Forissier    III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
1895a913ee7SJerome Forissier 
1905a913ee7SJerome Forissier    tmp = bb; bb = bbb; bbb = tmp;
1915a913ee7SJerome Forissier 
1925a913ee7SJerome Forissier    /* round 3 */
1935a913ee7SJerome Forissier    HH(dd, ee, aa, bb, cc, X[ 3], 11);
1945a913ee7SJerome Forissier    HH(cc, dd, ee, aa, bb, X[10], 13);
1955a913ee7SJerome Forissier    HH(bb, cc, dd, ee, aa, X[14],  6);
1965a913ee7SJerome Forissier    HH(aa, bb, cc, dd, ee, X[ 4],  7);
1975a913ee7SJerome Forissier    HH(ee, aa, bb, cc, dd, X[ 9], 14);
1985a913ee7SJerome Forissier    HH(dd, ee, aa, bb, cc, X[15],  9);
1995a913ee7SJerome Forissier    HH(cc, dd, ee, aa, bb, X[ 8], 13);
2005a913ee7SJerome Forissier    HH(bb, cc, dd, ee, aa, X[ 1], 15);
2015a913ee7SJerome Forissier    HH(aa, bb, cc, dd, ee, X[ 2], 14);
2025a913ee7SJerome Forissier    HH(ee, aa, bb, cc, dd, X[ 7],  8);
2035a913ee7SJerome Forissier    HH(dd, ee, aa, bb, cc, X[ 0], 13);
2045a913ee7SJerome Forissier    HH(cc, dd, ee, aa, bb, X[ 6],  6);
2055a913ee7SJerome Forissier    HH(bb, cc, dd, ee, aa, X[13],  5);
2065a913ee7SJerome Forissier    HH(aa, bb, cc, dd, ee, X[11], 12);
2075a913ee7SJerome Forissier    HH(ee, aa, bb, cc, dd, X[ 5],  7);
2085a913ee7SJerome Forissier    HH(dd, ee, aa, bb, cc, X[12],  5);
2095a913ee7SJerome Forissier 
2105a913ee7SJerome Forissier    /* parallel round 3 */
2115a913ee7SJerome Forissier    HHH(ddd, eee, aaa, bbb, ccc, X[15],  9);
2125a913ee7SJerome Forissier    HHH(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
2135a913ee7SJerome Forissier    HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
2145a913ee7SJerome Forissier    HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
2155a913ee7SJerome Forissier    HHH(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
2165a913ee7SJerome Forissier    HHH(ddd, eee, aaa, bbb, ccc, X[14],  6);
2175a913ee7SJerome Forissier    HHH(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
2185a913ee7SJerome Forissier    HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
2195a913ee7SJerome Forissier    HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
2205a913ee7SJerome Forissier    HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
2215a913ee7SJerome Forissier    HHH(ddd, eee, aaa, bbb, ccc, X[12],  5);
2225a913ee7SJerome Forissier    HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
2235a913ee7SJerome Forissier    HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
2245a913ee7SJerome Forissier    HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
2255a913ee7SJerome Forissier    HHH(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
2265a913ee7SJerome Forissier    HHH(ddd, eee, aaa, bbb, ccc, X[13],  5);
2275a913ee7SJerome Forissier 
2285a913ee7SJerome Forissier    tmp = cc; cc = ccc; ccc = tmp;
2295a913ee7SJerome Forissier 
2305a913ee7SJerome Forissier    /* round 4 */
2315a913ee7SJerome Forissier    II(cc, dd, ee, aa, bb, X[ 1], 11);
2325a913ee7SJerome Forissier    II(bb, cc, dd, ee, aa, X[ 9], 12);
2335a913ee7SJerome Forissier    II(aa, bb, cc, dd, ee, X[11], 14);
2345a913ee7SJerome Forissier    II(ee, aa, bb, cc, dd, X[10], 15);
2355a913ee7SJerome Forissier    II(dd, ee, aa, bb, cc, X[ 0], 14);
2365a913ee7SJerome Forissier    II(cc, dd, ee, aa, bb, X[ 8], 15);
2375a913ee7SJerome Forissier    II(bb, cc, dd, ee, aa, X[12],  9);
2385a913ee7SJerome Forissier    II(aa, bb, cc, dd, ee, X[ 4],  8);
2395a913ee7SJerome Forissier    II(ee, aa, bb, cc, dd, X[13],  9);
2405a913ee7SJerome Forissier    II(dd, ee, aa, bb, cc, X[ 3], 14);
2415a913ee7SJerome Forissier    II(cc, dd, ee, aa, bb, X[ 7],  5);
2425a913ee7SJerome Forissier    II(bb, cc, dd, ee, aa, X[15],  6);
2435a913ee7SJerome Forissier    II(aa, bb, cc, dd, ee, X[14],  8);
2445a913ee7SJerome Forissier    II(ee, aa, bb, cc, dd, X[ 5],  6);
2455a913ee7SJerome Forissier    II(dd, ee, aa, bb, cc, X[ 6],  5);
2465a913ee7SJerome Forissier    II(cc, dd, ee, aa, bb, X[ 2], 12);
2475a913ee7SJerome Forissier 
2485a913ee7SJerome Forissier    /* parallel round 4 */
2495a913ee7SJerome Forissier    GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
2505a913ee7SJerome Forissier    GGG(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
2515a913ee7SJerome Forissier    GGG(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
2525a913ee7SJerome Forissier    GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
2535a913ee7SJerome Forissier    GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
2545a913ee7SJerome Forissier    GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
2555a913ee7SJerome Forissier    GGG(bbb, ccc, ddd, eee, aaa, X[15],  6);
2565a913ee7SJerome Forissier    GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
2575a913ee7SJerome Forissier    GGG(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
2585a913ee7SJerome Forissier    GGG(ddd, eee, aaa, bbb, ccc, X[12],  9);
2595a913ee7SJerome Forissier    GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
2605a913ee7SJerome Forissier    GGG(bbb, ccc, ddd, eee, aaa, X[13],  9);
2615a913ee7SJerome Forissier    GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
2625a913ee7SJerome Forissier    GGG(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
2635a913ee7SJerome Forissier    GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
2645a913ee7SJerome Forissier    GGG(ccc, ddd, eee, aaa, bbb, X[14],  8);
2655a913ee7SJerome Forissier 
2665a913ee7SJerome Forissier    tmp = dd; dd = ddd; ddd = tmp;
2675a913ee7SJerome Forissier 
2685a913ee7SJerome Forissier    /* round 5 */
2695a913ee7SJerome Forissier    JJ(bb, cc, dd, ee, aa, X[ 4],  9);
2705a913ee7SJerome Forissier    JJ(aa, bb, cc, dd, ee, X[ 0], 15);
2715a913ee7SJerome Forissier    JJ(ee, aa, bb, cc, dd, X[ 5],  5);
2725a913ee7SJerome Forissier    JJ(dd, ee, aa, bb, cc, X[ 9], 11);
2735a913ee7SJerome Forissier    JJ(cc, dd, ee, aa, bb, X[ 7],  6);
2745a913ee7SJerome Forissier    JJ(bb, cc, dd, ee, aa, X[12],  8);
2755a913ee7SJerome Forissier    JJ(aa, bb, cc, dd, ee, X[ 2], 13);
2765a913ee7SJerome Forissier    JJ(ee, aa, bb, cc, dd, X[10], 12);
2775a913ee7SJerome Forissier    JJ(dd, ee, aa, bb, cc, X[14],  5);
2785a913ee7SJerome Forissier    JJ(cc, dd, ee, aa, bb, X[ 1], 12);
2795a913ee7SJerome Forissier    JJ(bb, cc, dd, ee, aa, X[ 3], 13);
2805a913ee7SJerome Forissier    JJ(aa, bb, cc, dd, ee, X[ 8], 14);
2815a913ee7SJerome Forissier    JJ(ee, aa, bb, cc, dd, X[11], 11);
2825a913ee7SJerome Forissier    JJ(dd, ee, aa, bb, cc, X[ 6],  8);
2835a913ee7SJerome Forissier    JJ(cc, dd, ee, aa, bb, X[15],  5);
2845a913ee7SJerome Forissier    JJ(bb, cc, dd, ee, aa, X[13],  6);
2855a913ee7SJerome Forissier 
2865a913ee7SJerome Forissier    /* parallel round 5 */
2875a913ee7SJerome Forissier    FFF(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
2885a913ee7SJerome Forissier    FFF(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
2895a913ee7SJerome Forissier    FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
2905a913ee7SJerome Forissier    FFF(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
2915a913ee7SJerome Forissier    FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
2925a913ee7SJerome Forissier    FFF(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
2935a913ee7SJerome Forissier    FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
2945a913ee7SJerome Forissier    FFF(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
2955a913ee7SJerome Forissier    FFF(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
2965a913ee7SJerome Forissier    FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
2975a913ee7SJerome Forissier    FFF(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
2985a913ee7SJerome Forissier    FFF(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
2995a913ee7SJerome Forissier    FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
3005a913ee7SJerome Forissier    FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
3015a913ee7SJerome Forissier    FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
3025a913ee7SJerome Forissier    FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
3035a913ee7SJerome Forissier 
3045a913ee7SJerome Forissier    tmp = ee; ee = eee; eee = tmp;
3055a913ee7SJerome Forissier 
3065a913ee7SJerome Forissier    /* combine results */
3075a913ee7SJerome Forissier    md->rmd320.state[0] += aa;
3085a913ee7SJerome Forissier    md->rmd320.state[1] += bb;
3095a913ee7SJerome Forissier    md->rmd320.state[2] += cc;
3105a913ee7SJerome Forissier    md->rmd320.state[3] += dd;
3115a913ee7SJerome Forissier    md->rmd320.state[4] += ee;
3125a913ee7SJerome Forissier    md->rmd320.state[5] += aaa;
3135a913ee7SJerome Forissier    md->rmd320.state[6] += bbb;
3145a913ee7SJerome Forissier    md->rmd320.state[7] += ccc;
3155a913ee7SJerome Forissier    md->rmd320.state[8] += ddd;
3165a913ee7SJerome Forissier    md->rmd320.state[9] += eee;
3175a913ee7SJerome Forissier 
3185a913ee7SJerome Forissier    return CRYPT_OK;
3195a913ee7SJerome Forissier }
3205a913ee7SJerome Forissier 
3215a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rmd320_compress(hash_state * md,const unsigned char * buf)322*8411e6adSJerome Forissier static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
3235a913ee7SJerome Forissier {
3245a913ee7SJerome Forissier    int err;
325*8411e6adSJerome Forissier    err = ss_rmd320_compress(md, buf);
3265a913ee7SJerome Forissier    burn_stack(sizeof(ulong32) * 27 + sizeof(int));
3275a913ee7SJerome Forissier    return err;
3285a913ee7SJerome Forissier }
3295a913ee7SJerome Forissier #endif
3305a913ee7SJerome Forissier 
3315a913ee7SJerome Forissier /**
3325a913ee7SJerome Forissier    Initialize the hash state
3335a913ee7SJerome Forissier    @param md   The hash state you wish to initialize
3345a913ee7SJerome Forissier    @return CRYPT_OK if successful
3355a913ee7SJerome Forissier */
rmd320_init(hash_state * md)3365a913ee7SJerome Forissier int rmd320_init(hash_state * md)
3375a913ee7SJerome Forissier {
3385a913ee7SJerome Forissier    LTC_ARGCHK(md != NULL);
3395a913ee7SJerome Forissier    md->rmd320.state[0] = 0x67452301UL;
3405a913ee7SJerome Forissier    md->rmd320.state[1] = 0xefcdab89UL;
3415a913ee7SJerome Forissier    md->rmd320.state[2] = 0x98badcfeUL;
3425a913ee7SJerome Forissier    md->rmd320.state[3] = 0x10325476UL;
3435a913ee7SJerome Forissier    md->rmd320.state[4] = 0xc3d2e1f0UL;
3445a913ee7SJerome Forissier    md->rmd320.state[5] = 0x76543210UL;
3455a913ee7SJerome Forissier    md->rmd320.state[6] = 0xfedcba98UL;
3465a913ee7SJerome Forissier    md->rmd320.state[7] = 0x89abcdefUL;
3475a913ee7SJerome Forissier    md->rmd320.state[8] = 0x01234567UL;
3485a913ee7SJerome Forissier    md->rmd320.state[9] = 0x3c2d1e0fUL;
3495a913ee7SJerome Forissier    md->rmd320.curlen   = 0;
3505a913ee7SJerome Forissier    md->rmd320.length   = 0;
3515a913ee7SJerome Forissier    return CRYPT_OK;
3525a913ee7SJerome Forissier }
3535a913ee7SJerome Forissier 
3545a913ee7SJerome Forissier /**
3555a913ee7SJerome Forissier    Process a block of memory though the hash
3565a913ee7SJerome Forissier    @param md     The hash state
3575a913ee7SJerome Forissier    @param in     The data to hash
3585a913ee7SJerome Forissier    @param inlen  The length of the data (octets)
3595a913ee7SJerome Forissier    @return CRYPT_OK if successful
3605a913ee7SJerome Forissier */
361*8411e6adSJerome Forissier HASH_PROCESS(rmd320_process, s_rmd320_compress, rmd320, 64)
3625a913ee7SJerome Forissier 
3635a913ee7SJerome Forissier /**
3645a913ee7SJerome Forissier    Terminate the hash to get the digest
3655a913ee7SJerome Forissier    @param md  The hash state
3665a913ee7SJerome Forissier    @param out [out] The destination of the hash (20 bytes)
3675a913ee7SJerome Forissier    @return CRYPT_OK if successful
3685a913ee7SJerome Forissier */
rmd320_done(hash_state * md,unsigned char * out)3695a913ee7SJerome Forissier int rmd320_done(hash_state * md, unsigned char *out)
3705a913ee7SJerome Forissier {
3715a913ee7SJerome Forissier     int i;
3725a913ee7SJerome Forissier 
3735a913ee7SJerome Forissier     LTC_ARGCHK(md  != NULL);
3745a913ee7SJerome Forissier     LTC_ARGCHK(out != NULL);
3755a913ee7SJerome Forissier 
3765a913ee7SJerome Forissier     if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
3775a913ee7SJerome Forissier        return CRYPT_INVALID_ARG;
3785a913ee7SJerome Forissier     }
3795a913ee7SJerome Forissier 
3805a913ee7SJerome Forissier 
3815a913ee7SJerome Forissier     /* increase the length of the message */
3825a913ee7SJerome Forissier     md->rmd320.length += md->rmd320.curlen * 8;
3835a913ee7SJerome Forissier 
3845a913ee7SJerome Forissier     /* append the '1' bit */
3855a913ee7SJerome Forissier     md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
3865a913ee7SJerome Forissier 
3875a913ee7SJerome Forissier     /* if the length is currently above 56 bytes we append zeros
3885a913ee7SJerome Forissier      * then compress.  Then we can fall back to padding zeros and length
3895a913ee7SJerome Forissier      * encoding like normal.
3905a913ee7SJerome Forissier      */
3915a913ee7SJerome Forissier     if (md->rmd320.curlen > 56) {
3925a913ee7SJerome Forissier         while (md->rmd320.curlen < 64) {
3935a913ee7SJerome Forissier             md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
3945a913ee7SJerome Forissier         }
395*8411e6adSJerome Forissier         s_rmd320_compress(md, md->rmd320.buf);
3965a913ee7SJerome Forissier         md->rmd320.curlen = 0;
3975a913ee7SJerome Forissier     }
3985a913ee7SJerome Forissier 
3995a913ee7SJerome Forissier     /* pad upto 56 bytes of zeroes */
4005a913ee7SJerome Forissier     while (md->rmd320.curlen < 56) {
4015a913ee7SJerome Forissier         md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
4025a913ee7SJerome Forissier     }
4035a913ee7SJerome Forissier 
4045a913ee7SJerome Forissier     /* store length */
4055a913ee7SJerome Forissier     STORE64L(md->rmd320.length, md->rmd320.buf+56);
406*8411e6adSJerome Forissier     s_rmd320_compress(md, md->rmd320.buf);
4075a913ee7SJerome Forissier 
4085a913ee7SJerome Forissier     /* copy output */
4095a913ee7SJerome Forissier     for (i = 0; i < 10; i++) {
4105a913ee7SJerome Forissier         STORE32L(md->rmd320.state[i], out+(4*i));
4115a913ee7SJerome Forissier     }
4125a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
4135a913ee7SJerome Forissier     zeromem(md, sizeof(hash_state));
4145a913ee7SJerome Forissier #endif
4155a913ee7SJerome Forissier     return CRYPT_OK;
4165a913ee7SJerome Forissier }
4175a913ee7SJerome Forissier 
4185a913ee7SJerome Forissier /**
4195a913ee7SJerome Forissier   Self-test the hash
4205a913ee7SJerome Forissier   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
4215a913ee7SJerome Forissier */
rmd320_test(void)4225a913ee7SJerome Forissier int rmd320_test(void)
4235a913ee7SJerome Forissier {
4245a913ee7SJerome Forissier #ifndef LTC_TEST
4255a913ee7SJerome Forissier    return CRYPT_NOP;
4265a913ee7SJerome Forissier #else
4275a913ee7SJerome Forissier    static const struct {
4285a913ee7SJerome Forissier         const char *msg;
4295a913ee7SJerome Forissier         unsigned char hash[40];
4305a913ee7SJerome Forissier    } tests[] = {
4315a913ee7SJerome Forissier    { "",
4325a913ee7SJerome Forissier      { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
4335a913ee7SJerome Forissier        0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
4345a913ee7SJerome Forissier        0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
4355a913ee7SJerome Forissier        0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
4365a913ee7SJerome Forissier    },
4375a913ee7SJerome Forissier    { "a",
4385a913ee7SJerome Forissier      { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
4395a913ee7SJerome Forissier        0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
4405a913ee7SJerome Forissier        0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
4415a913ee7SJerome Forissier        0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
4425a913ee7SJerome Forissier    },
4435a913ee7SJerome Forissier    { "abc",
4445a913ee7SJerome Forissier      { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
4455a913ee7SJerome Forissier        0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
4465a913ee7SJerome Forissier        0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
4475a913ee7SJerome Forissier        0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
4485a913ee7SJerome Forissier    },
4495a913ee7SJerome Forissier    { "message digest",
4505a913ee7SJerome Forissier      { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
4515a913ee7SJerome Forissier        0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
4525a913ee7SJerome Forissier        0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
4535a913ee7SJerome Forissier        0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
4545a913ee7SJerome Forissier    },
4555a913ee7SJerome Forissier    { "abcdefghijklmnopqrstuvwxyz",
4565a913ee7SJerome Forissier      { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
4575a913ee7SJerome Forissier        0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
4585a913ee7SJerome Forissier        0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
4595a913ee7SJerome Forissier        0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
4605a913ee7SJerome Forissier    },
4615a913ee7SJerome Forissier    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
4625a913ee7SJerome Forissier      { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
4635a913ee7SJerome Forissier        0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
4645a913ee7SJerome Forissier        0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
4655a913ee7SJerome Forissier        0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
4665a913ee7SJerome Forissier    }
4675a913ee7SJerome Forissier    };
4685a913ee7SJerome Forissier 
4695a913ee7SJerome Forissier    int i;
4705a913ee7SJerome Forissier    unsigned char tmp[40];
4715a913ee7SJerome Forissier    hash_state md;
4725a913ee7SJerome Forissier 
4735a913ee7SJerome Forissier    for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
4745a913ee7SJerome Forissier        rmd320_init(&md);
475*8411e6adSJerome Forissier        rmd320_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
4765a913ee7SJerome Forissier        rmd320_done(&md, tmp);
4775a913ee7SJerome Forissier        if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD320", i)) {
4785a913ee7SJerome Forissier           return CRYPT_FAIL_TESTVECTOR;
4795a913ee7SJerome Forissier        }
4805a913ee7SJerome Forissier    }
4815a913ee7SJerome Forissier    return CRYPT_OK;
4825a913ee7SJerome Forissier #endif
4835a913ee7SJerome Forissier }
4845a913ee7SJerome Forissier 
4855a913ee7SJerome Forissier #endif
486