1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6    @param rmd128.c
7    RMD128 Hash function
8 */
9 
10 /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
11  *
12  * This source has been radically overhauled to be portable and work within
13  * the LibTomCrypt API by Tom St Denis
14  */
15 
16 #ifdef LTC_RIPEMD128
17 
18 const struct ltc_hash_descriptor rmd128_desc =
19 {
20     "rmd128",
21     8,
22     16,
23     64,
24 
25     /* OID */
26    { 1, 0, 10118, 3, 0, 50 },
27    6,
28 
29     &rmd128_init,
30     &rmd128_process,
31     &rmd128_done,
32     &rmd128_test,
33     NULL
34 };
35 
36 /* the four basic functions F(), G() and H() */
37 #define F(x, y, z)        ((x) ^ (y) ^ (z))
38 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
39 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
40 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
41 
42 /* the eight basic operations FF() through III() */
43 #define FF(a, b, c, d, x, s)        \
44       (a) += F((b), (c), (d)) + (x);\
45       (a) = ROLc((a), (s));
46 
47 #define GG(a, b, c, d, x, s)        \
48       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
49       (a) = ROLc((a), (s));
50 
51 #define HH(a, b, c, d, x, s)        \
52       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
53       (a) = ROLc((a), (s));
54 
55 #define II(a, b, c, d, x, s)        \
56       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
57       (a) = ROLc((a), (s));
58 
59 #define FFF(a, b, c, d, x, s)        \
60       (a) += F((b), (c), (d)) + (x);\
61       (a) = ROLc((a), (s));
62 
63 #define GGG(a, b, c, d, x, s)        \
64       (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
65       (a) = ROLc((a), (s));
66 
67 #define HHH(a, b, c, d, x, s)        \
68       (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
69       (a) = ROLc((a), (s));
70 
71 #define III(a, b, c, d, x, s)        \
72       (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
73       (a) = ROLc((a), (s));
74 
75 #ifdef LTC_CLEAN_STACK
ss_rmd128_compress(hash_state * md,const unsigned char * buf)76 static int ss_rmd128_compress(hash_state *md, const unsigned char *buf)
77 #else
78 static int  s_rmd128_compress(hash_state *md, const unsigned char *buf)
79 #endif
80 {
81    ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
82    int i;
83 
84    /* load words X */
85    for (i = 0; i < 16; i++){
86       LOAD32L(X[i], buf + (4 * i));
87    }
88 
89    /* load state */
90    aa = aaa = md->rmd128.state[0];
91    bb = bbb = md->rmd128.state[1];
92    cc = ccc = md->rmd128.state[2];
93    dd = ddd = md->rmd128.state[3];
94 
95    /* round 1 */
96    FF(aa, bb, cc, dd, X[ 0], 11);
97    FF(dd, aa, bb, cc, X[ 1], 14);
98    FF(cc, dd, aa, bb, X[ 2], 15);
99    FF(bb, cc, dd, aa, X[ 3], 12);
100    FF(aa, bb, cc, dd, X[ 4],  5);
101    FF(dd, aa, bb, cc, X[ 5],  8);
102    FF(cc, dd, aa, bb, X[ 6],  7);
103    FF(bb, cc, dd, aa, X[ 7],  9);
104    FF(aa, bb, cc, dd, X[ 8], 11);
105    FF(dd, aa, bb, cc, X[ 9], 13);
106    FF(cc, dd, aa, bb, X[10], 14);
107    FF(bb, cc, dd, aa, X[11], 15);
108    FF(aa, bb, cc, dd, X[12],  6);
109    FF(dd, aa, bb, cc, X[13],  7);
110    FF(cc, dd, aa, bb, X[14],  9);
111    FF(bb, cc, dd, aa, X[15],  8);
112 
113    /* round 2 */
114    GG(aa, bb, cc, dd, X[ 7],  7);
115    GG(dd, aa, bb, cc, X[ 4],  6);
116    GG(cc, dd, aa, bb, X[13],  8);
117    GG(bb, cc, dd, aa, X[ 1], 13);
118    GG(aa, bb, cc, dd, X[10], 11);
119    GG(dd, aa, bb, cc, X[ 6],  9);
120    GG(cc, dd, aa, bb, X[15],  7);
121    GG(bb, cc, dd, aa, X[ 3], 15);
122    GG(aa, bb, cc, dd, X[12],  7);
123    GG(dd, aa, bb, cc, X[ 0], 12);
124    GG(cc, dd, aa, bb, X[ 9], 15);
125    GG(bb, cc, dd, aa, X[ 5],  9);
126    GG(aa, bb, cc, dd, X[ 2], 11);
127    GG(dd, aa, bb, cc, X[14],  7);
128    GG(cc, dd, aa, bb, X[11], 13);
129    GG(bb, cc, dd, aa, X[ 8], 12);
130 
131    /* round 3 */
132    HH(aa, bb, cc, dd, X[ 3], 11);
133    HH(dd, aa, bb, cc, X[10], 13);
134    HH(cc, dd, aa, bb, X[14],  6);
135    HH(bb, cc, dd, aa, X[ 4],  7);
136    HH(aa, bb, cc, dd, X[ 9], 14);
137    HH(dd, aa, bb, cc, X[15],  9);
138    HH(cc, dd, aa, bb, X[ 8], 13);
139    HH(bb, cc, dd, aa, X[ 1], 15);
140    HH(aa, bb, cc, dd, X[ 2], 14);
141    HH(dd, aa, bb, cc, X[ 7],  8);
142    HH(cc, dd, aa, bb, X[ 0], 13);
143    HH(bb, cc, dd, aa, X[ 6],  6);
144    HH(aa, bb, cc, dd, X[13],  5);
145    HH(dd, aa, bb, cc, X[11], 12);
146    HH(cc, dd, aa, bb, X[ 5],  7);
147    HH(bb, cc, dd, aa, X[12],  5);
148 
149    /* round 4 */
150    II(aa, bb, cc, dd, X[ 1], 11);
151    II(dd, aa, bb, cc, X[ 9], 12);
152    II(cc, dd, aa, bb, X[11], 14);
153    II(bb, cc, dd, aa, X[10], 15);
154    II(aa, bb, cc, dd, X[ 0], 14);
155    II(dd, aa, bb, cc, X[ 8], 15);
156    II(cc, dd, aa, bb, X[12],  9);
157    II(bb, cc, dd, aa, X[ 4],  8);
158    II(aa, bb, cc, dd, X[13],  9);
159    II(dd, aa, bb, cc, X[ 3], 14);
160    II(cc, dd, aa, bb, X[ 7],  5);
161    II(bb, cc, dd, aa, X[15],  6);
162    II(aa, bb, cc, dd, X[14],  8);
163    II(dd, aa, bb, cc, X[ 5],  6);
164    II(cc, dd, aa, bb, X[ 6],  5);
165    II(bb, cc, dd, aa, X[ 2], 12);
166 
167    /* parallel round 1 */
168    III(aaa, bbb, ccc, ddd, X[ 5],  8);
169    III(ddd, aaa, bbb, ccc, X[14],  9);
170    III(ccc, ddd, aaa, bbb, X[ 7],  9);
171    III(bbb, ccc, ddd, aaa, X[ 0], 11);
172    III(aaa, bbb, ccc, ddd, X[ 9], 13);
173    III(ddd, aaa, bbb, ccc, X[ 2], 15);
174    III(ccc, ddd, aaa, bbb, X[11], 15);
175    III(bbb, ccc, ddd, aaa, X[ 4],  5);
176    III(aaa, bbb, ccc, ddd, X[13],  7);
177    III(ddd, aaa, bbb, ccc, X[ 6],  7);
178    III(ccc, ddd, aaa, bbb, X[15],  8);
179    III(bbb, ccc, ddd, aaa, X[ 8], 11);
180    III(aaa, bbb, ccc, ddd, X[ 1], 14);
181    III(ddd, aaa, bbb, ccc, X[10], 14);
182    III(ccc, ddd, aaa, bbb, X[ 3], 12);
183    III(bbb, ccc, ddd, aaa, X[12],  6);
184 
185    /* parallel round 2 */
186    HHH(aaa, bbb, ccc, ddd, X[ 6],  9);
187    HHH(ddd, aaa, bbb, ccc, X[11], 13);
188    HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
189    HHH(bbb, ccc, ddd, aaa, X[ 7],  7);
190    HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
191    HHH(ddd, aaa, bbb, ccc, X[13],  8);
192    HHH(ccc, ddd, aaa, bbb, X[ 5],  9);
193    HHH(bbb, ccc, ddd, aaa, X[10], 11);
194    HHH(aaa, bbb, ccc, ddd, X[14],  7);
195    HHH(ddd, aaa, bbb, ccc, X[15],  7);
196    HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
197    HHH(bbb, ccc, ddd, aaa, X[12],  7);
198    HHH(aaa, bbb, ccc, ddd, X[ 4],  6);
199    HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
200    HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
201    HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
202 
203    /* parallel round 3 */
204    GGG(aaa, bbb, ccc, ddd, X[15],  9);
205    GGG(ddd, aaa, bbb, ccc, X[ 5],  7);
206    GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
207    GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
208    GGG(aaa, bbb, ccc, ddd, X[ 7],  8);
209    GGG(ddd, aaa, bbb, ccc, X[14],  6);
210    GGG(ccc, ddd, aaa, bbb, X[ 6],  6);
211    GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
212    GGG(aaa, bbb, ccc, ddd, X[11], 12);
213    GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
214    GGG(ccc, ddd, aaa, bbb, X[12],  5);
215    GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
216    GGG(aaa, bbb, ccc, ddd, X[10], 13);
217    GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
218    GGG(ccc, ddd, aaa, bbb, X[ 4],  7);
219    GGG(bbb, ccc, ddd, aaa, X[13],  5);
220 
221    /* parallel round 4 */
222    FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
223    FFF(ddd, aaa, bbb, ccc, X[ 6],  5);
224    FFF(ccc, ddd, aaa, bbb, X[ 4],  8);
225    FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
226    FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
227    FFF(ddd, aaa, bbb, ccc, X[11], 14);
228    FFF(ccc, ddd, aaa, bbb, X[15],  6);
229    FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
230    FFF(aaa, bbb, ccc, ddd, X[ 5],  6);
231    FFF(ddd, aaa, bbb, ccc, X[12],  9);
232    FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
233    FFF(bbb, ccc, ddd, aaa, X[13],  9);
234    FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
235    FFF(ddd, aaa, bbb, ccc, X[ 7],  5);
236    FFF(ccc, ddd, aaa, bbb, X[10], 15);
237    FFF(bbb, ccc, ddd, aaa, X[14],  8);
238 
239    /* combine results */
240    ddd += cc + md->rmd128.state[1];               /* final result for MDbuf[0] */
241    md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
242    md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
243    md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
244    md->rmd128.state[0] = ddd;
245 
246    return CRYPT_OK;
247 }
248 
249 #ifdef LTC_CLEAN_STACK
s_rmd128_compress(hash_state * md,const unsigned char * buf)250 static int s_rmd128_compress(hash_state *md, const unsigned char *buf)
251 {
252    int err;
253    err = ss_rmd128_compress(md, buf);
254    burn_stack(sizeof(ulong32) * 24 + sizeof(int));
255    return err;
256 }
257 #endif
258 
259 /**
260    Initialize the hash state
261    @param md   The hash state you wish to initialize
262    @return CRYPT_OK if successful
263 */
rmd128_init(hash_state * md)264 int rmd128_init(hash_state * md)
265 {
266    LTC_ARGCHK(md != NULL);
267    md->rmd128.state[0] = 0x67452301UL;
268    md->rmd128.state[1] = 0xefcdab89UL;
269    md->rmd128.state[2] = 0x98badcfeUL;
270    md->rmd128.state[3] = 0x10325476UL;
271    md->rmd128.curlen   = 0;
272    md->rmd128.length   = 0;
273    return CRYPT_OK;
274 }
275 
276 /**
277    Process a block of memory though the hash
278    @param md     The hash state
279    @param in     The data to hash
280    @param inlen  The length of the data (octets)
281    @return CRYPT_OK if successful
282 */
283 HASH_PROCESS(rmd128_process, s_rmd128_compress, rmd128, 64)
284 
285 /**
286    Terminate the hash to get the digest
287    @param md  The hash state
288    @param out [out] The destination of the hash (16 bytes)
289    @return CRYPT_OK if successful
290 */
rmd128_done(hash_state * md,unsigned char * out)291 int rmd128_done(hash_state * md, unsigned char *out)
292 {
293     int i;
294 
295     LTC_ARGCHK(md  != NULL);
296     LTC_ARGCHK(out != NULL);
297 
298     if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
299        return CRYPT_INVALID_ARG;
300     }
301 
302 
303     /* increase the length of the message */
304     md->rmd128.length += md->rmd128.curlen * 8;
305 
306     /* append the '1' bit */
307     md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
308 
309     /* if the length is currently above 56 bytes we append zeros
310      * then compress.  Then we can fall back to padding zeros and length
311      * encoding like normal.
312      */
313     if (md->rmd128.curlen > 56) {
314         while (md->rmd128.curlen < 64) {
315             md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
316         }
317         s_rmd128_compress(md, md->rmd128.buf);
318         md->rmd128.curlen = 0;
319     }
320 
321     /* pad upto 56 bytes of zeroes */
322     while (md->rmd128.curlen < 56) {
323         md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
324     }
325 
326     /* store length */
327     STORE64L(md->rmd128.length, md->rmd128.buf+56);
328     s_rmd128_compress(md, md->rmd128.buf);
329 
330     /* copy output */
331     for (i = 0; i < 4; i++) {
332         STORE32L(md->rmd128.state[i], out+(4*i));
333     }
334 #ifdef LTC_CLEAN_STACK
335     zeromem(md, sizeof(hash_state));
336 #endif
337    return CRYPT_OK;
338 }
339 
340 /**
341   Self-test the hash
342   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
343 */
rmd128_test(void)344 int rmd128_test(void)
345 {
346 #ifndef LTC_TEST
347    return CRYPT_NOP;
348 #else
349    static const struct {
350         const char *msg;
351         unsigned char hash[16];
352    } tests[] = {
353    { "",
354      { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
355        0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
356    },
357    { "a",
358      { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
359        0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
360    },
361    { "abc",
362      { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
363        0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
364    },
365    { "message digest",
366      { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
367        0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
368    },
369    { "abcdefghijklmnopqrstuvwxyz",
370      { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
371        0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
372    },
373    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
374      { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
375        0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
376    }
377    };
378 
379    int i;
380    unsigned char tmp[16];
381    hash_state md;
382 
383    for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
384        rmd128_init(&md);
385        rmd128_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
386        rmd128_done(&md, tmp);
387        if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD128", i)) {
388           return CRYPT_FAIL_TESTVECTOR;
389        }
390    }
391    return CRYPT_OK;
392 #endif
393 }
394 
395 #endif
396 
397