Home | History | Annotate | Download | only in hashes
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 #include "tomcrypt.h"
     12 
     13 /**
     14    @param rmd256.c
     15    RMD256 Hash function
     16 */
     17 
     18 #ifdef RIPEMD256
     19 
     20 const struct ltc_hash_descriptor rmd256_desc =
     21 {
     22     "rmd256",
     23     8,
     24     16,
     25     64,
     26 
     27     /* OID */
     28    { 1, 3, 36, 3, 2, 3 },
     29    6,
     30 
     31     &rmd256_init,
     32     &rmd256_process,
     33     &rmd256_done,
     34     &rmd256_test,
     35     NULL
     36 };
     37 
     38 /* the four basic functions F(), G() and H() */
     39 #define F(x, y, z)        ((x) ^ (y) ^ (z))
     40 #define G(x, y, z)        (((x) & (y)) | (~(x) & (z)))
     41 #define H(x, y, z)        (((x) | ~(y)) ^ (z))
     42 #define I(x, y, z)        (((x) & (z)) | ((y) & ~(z)))
     43 
     44 /* the eight basic operations FF() through III() */
     45 #define FF(a, b, c, d, x, s)        \
     46       (a) += F((b), (c), (d)) + (x);\
     47       (a) = ROLc((a), (s));
     48 
     49 #define GG(a, b, c, d, x, s)        \
     50       (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
     51       (a) = ROLc((a), (s));
     52 
     53 #define HH(a, b, c, d, x, s)        \
     54       (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
     55       (a) = ROLc((a), (s));
     56 
     57 #define II(a, b, c, d, x, s)        \
     58       (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
     59       (a) = ROLc((a), (s));
     60 
     61 #define FFF(a, b, c, d, x, s)        \
     62       (a) += F((b), (c), (d)) + (x);\
     63       (a) = ROLc((a), (s));
     64 
     65 #define GGG(a, b, c, d, x, s)        \
     66       (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
     67       (a) = ROLc((a), (s));
     68 
     69 #define HHH(a, b, c, d, x, s)        \
     70       (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
     71       (a) = ROLc((a), (s));
     72 
     73 #define III(a, b, c, d, x, s)        \
     74       (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
     75       (a) = ROLc((a), (s));
     76 
     77 #ifdef LTC_CLEAN_STACK
     78 static int _rmd256_compress(hash_state *md, unsigned char *buf)
     79 #else
     80 static int  rmd256_compress(hash_state *md, unsigned char *buf)
     81 #endif
     82 {
     83    ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16];
     84    int i;
     85 
     86    /* load words X */
     87    for (i = 0; i < 16; i++){
     88       LOAD32L(X[i], buf + (4 * i));
     89    }
     90 
     91    /* load state */
     92    aa = md->rmd256.state[0];
     93    bb = md->rmd256.state[1];
     94    cc = md->rmd256.state[2];
     95    dd = md->rmd256.state[3];
     96    aaa = md->rmd256.state[4];
     97    bbb = md->rmd256.state[5];
     98    ccc = md->rmd256.state[6];
     99    ddd = md->rmd256.state[7];
    100 
    101    /* round 1 */
    102    FF(aa, bb, cc, dd, X[ 0], 11);
    103    FF(dd, aa, bb, cc, X[ 1], 14);
    104    FF(cc, dd, aa, bb, X[ 2], 15);
    105    FF(bb, cc, dd, aa, X[ 3], 12);
    106    FF(aa, bb, cc, dd, X[ 4],  5);
    107    FF(dd, aa, bb, cc, X[ 5],  8);
    108    FF(cc, dd, aa, bb, X[ 6],  7);
    109    FF(bb, cc, dd, aa, X[ 7],  9);
    110    FF(aa, bb, cc, dd, X[ 8], 11);
    111    FF(dd, aa, bb, cc, X[ 9], 13);
    112    FF(cc, dd, aa, bb, X[10], 14);
    113    FF(bb, cc, dd, aa, X[11], 15);
    114    FF(aa, bb, cc, dd, X[12],  6);
    115    FF(dd, aa, bb, cc, X[13],  7);
    116    FF(cc, dd, aa, bb, X[14],  9);
    117    FF(bb, cc, dd, aa, X[15],  8);
    118 
    119    /* parallel round 1 */
    120    III(aaa, bbb, ccc, ddd, X[ 5],  8);
    121    III(ddd, aaa, bbb, ccc, X[14],  9);
    122    III(ccc, ddd, aaa, bbb, X[ 7],  9);
    123    III(bbb, ccc, ddd, aaa, X[ 0], 11);
    124    III(aaa, bbb, ccc, ddd, X[ 9], 13);
    125    III(ddd, aaa, bbb, ccc, X[ 2], 15);
    126    III(ccc, ddd, aaa, bbb, X[11], 15);
    127    III(bbb, ccc, ddd, aaa, X[ 4],  5);
    128    III(aaa, bbb, ccc, ddd, X[13],  7);
    129    III(ddd, aaa, bbb, ccc, X[ 6],  7);
    130    III(ccc, ddd, aaa, bbb, X[15],  8);
    131    III(bbb, ccc, ddd, aaa, X[ 8], 11);
    132    III(aaa, bbb, ccc, ddd, X[ 1], 14);
    133    III(ddd, aaa, bbb, ccc, X[10], 14);
    134    III(ccc, ddd, aaa, bbb, X[ 3], 12);
    135    III(bbb, ccc, ddd, aaa, X[12],  6);
    136 
    137    tmp = aa; aa = aaa; aaa = tmp;
    138 
    139    /* round 2 */
    140    GG(aa, bb, cc, dd, X[ 7],  7);
    141    GG(dd, aa, bb, cc, X[ 4],  6);
    142    GG(cc, dd, aa, bb, X[13],  8);
    143    GG(bb, cc, dd, aa, X[ 1], 13);
    144    GG(aa, bb, cc, dd, X[10], 11);
    145    GG(dd, aa, bb, cc, X[ 6],  9);
    146    GG(cc, dd, aa, bb, X[15],  7);
    147    GG(bb, cc, dd, aa, X[ 3], 15);
    148    GG(aa, bb, cc, dd, X[12],  7);
    149    GG(dd, aa, bb, cc, X[ 0], 12);
    150    GG(cc, dd, aa, bb, X[ 9], 15);
    151    GG(bb, cc, dd, aa, X[ 5],  9);
    152    GG(aa, bb, cc, dd, X[ 2], 11);
    153    GG(dd, aa, bb, cc, X[14],  7);
    154    GG(cc, dd, aa, bb, X[11], 13);
    155    GG(bb, cc, dd, aa, X[ 8], 12);
    156 
    157    /* parallel round 2 */
    158    HHH(aaa, bbb, ccc, ddd, X[ 6],  9);
    159    HHH(ddd, aaa, bbb, ccc, X[11], 13);
    160    HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
    161    HHH(bbb, ccc, ddd, aaa, X[ 7],  7);
    162    HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
    163    HHH(ddd, aaa, bbb, ccc, X[13],  8);
    164    HHH(ccc, ddd, aaa, bbb, X[ 5],  9);
    165    HHH(bbb, ccc, ddd, aaa, X[10], 11);
    166    HHH(aaa, bbb, ccc, ddd, X[14],  7);
    167    HHH(ddd, aaa, bbb, ccc, X[15],  7);
    168    HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
    169    HHH(bbb, ccc, ddd, aaa, X[12],  7);
    170    HHH(aaa, bbb, ccc, ddd, X[ 4],  6);
    171    HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
    172    HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
    173    HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
    174 
    175    tmp = bb; bb = bbb; bbb = tmp;
    176 
    177    /* round 3 */
    178    HH(aa, bb, cc, dd, X[ 3], 11);
    179    HH(dd, aa, bb, cc, X[10], 13);
    180    HH(cc, dd, aa, bb, X[14],  6);
    181    HH(bb, cc, dd, aa, X[ 4],  7);
    182    HH(aa, bb, cc, dd, X[ 9], 14);
    183    HH(dd, aa, bb, cc, X[15],  9);
    184    HH(cc, dd, aa, bb, X[ 8], 13);
    185    HH(bb, cc, dd, aa, X[ 1], 15);
    186    HH(aa, bb, cc, dd, X[ 2], 14);
    187    HH(dd, aa, bb, cc, X[ 7],  8);
    188    HH(cc, dd, aa, bb, X[ 0], 13);
    189    HH(bb, cc, dd, aa, X[ 6],  6);
    190    HH(aa, bb, cc, dd, X[13],  5);
    191    HH(dd, aa, bb, cc, X[11], 12);
    192    HH(cc, dd, aa, bb, X[ 5],  7);
    193    HH(bb, cc, dd, aa, X[12],  5);
    194 
    195    /* parallel round 3 */
    196    GGG(aaa, bbb, ccc, ddd, X[15],  9);
    197    GGG(ddd, aaa, bbb, ccc, X[ 5],  7);
    198    GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
    199    GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
    200    GGG(aaa, bbb, ccc, ddd, X[ 7],  8);
    201    GGG(ddd, aaa, bbb, ccc, X[14],  6);
    202    GGG(ccc, ddd, aaa, bbb, X[ 6],  6);
    203    GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
    204    GGG(aaa, bbb, ccc, ddd, X[11], 12);
    205    GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
    206    GGG(ccc, ddd, aaa, bbb, X[12],  5);
    207    GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
    208    GGG(aaa, bbb, ccc, ddd, X[10], 13);
    209    GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
    210    GGG(ccc, ddd, aaa, bbb, X[ 4],  7);
    211    GGG(bbb, ccc, ddd, aaa, X[13],  5);
    212 
    213    tmp = cc; cc = ccc; ccc = tmp;
    214 
    215    /* round 4 */
    216    II(aa, bb, cc, dd, X[ 1], 11);
    217    II(dd, aa, bb, cc, X[ 9], 12);
    218    II(cc, dd, aa, bb, X[11], 14);
    219    II(bb, cc, dd, aa, X[10], 15);
    220    II(aa, bb, cc, dd, X[ 0], 14);
    221    II(dd, aa, bb, cc, X[ 8], 15);
    222    II(cc, dd, aa, bb, X[12],  9);
    223    II(bb, cc, dd, aa, X[ 4],  8);
    224    II(aa, bb, cc, dd, X[13],  9);
    225    II(dd, aa, bb, cc, X[ 3], 14);
    226    II(cc, dd, aa, bb, X[ 7],  5);
    227    II(bb, cc, dd, aa, X[15],  6);
    228    II(aa, bb, cc, dd, X[14],  8);
    229    II(dd, aa, bb, cc, X[ 5],  6);
    230    II(cc, dd, aa, bb, X[ 6],  5);
    231    II(bb, cc, dd, aa, X[ 2], 12);
    232 
    233    /* parallel round 4 */
    234    FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
    235    FFF(ddd, aaa, bbb, ccc, X[ 6],  5);
    236    FFF(ccc, ddd, aaa, bbb, X[ 4],  8);
    237    FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
    238    FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
    239    FFF(ddd, aaa, bbb, ccc, X[11], 14);
    240    FFF(ccc, ddd, aaa, bbb, X[15],  6);
    241    FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
    242    FFF(aaa, bbb, ccc, ddd, X[ 5],  6);
    243    FFF(ddd, aaa, bbb, ccc, X[12],  9);
    244    FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
    245    FFF(bbb, ccc, ddd, aaa, X[13],  9);
    246    FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
    247    FFF(ddd, aaa, bbb, ccc, X[ 7],  5);
    248    FFF(ccc, ddd, aaa, bbb, X[10], 15);
    249    FFF(bbb, ccc, ddd, aaa, X[14],  8);
    250 
    251    tmp = dd; dd = ddd; ddd = tmp;
    252 
    253    /* combine results */
    254    md->rmd256.state[0] += aa;
    255    md->rmd256.state[1] += bb;
    256    md->rmd256.state[2] += cc;
    257    md->rmd256.state[3] += dd;
    258    md->rmd256.state[4] += aaa;
    259    md->rmd256.state[5] += bbb;
    260    md->rmd256.state[6] += ccc;
    261    md->rmd256.state[7] += ddd;
    262 
    263    return CRYPT_OK;
    264 }
    265 
    266 #ifdef LTC_CLEAN_STACK
    267 static int rmd256_compress(hash_state *md, unsigned char *buf)
    268 {
    269    int err;
    270    err = _rmd256_compress(md, buf);
    271    burn_stack(sizeof(ulong32) * 25 + sizeof(int));
    272    return err;
    273 }
    274 #endif
    275 
    276 /**
    277    Initialize the hash state
    278    @param md   The hash state you wish to initialize
    279    @return CRYPT_OK if successful
    280 */
    281 int rmd256_init(hash_state * md)
    282 {
    283    LTC_ARGCHK(md != NULL);
    284    md->rmd256.state[0] = 0x67452301UL;
    285    md->rmd256.state[1] = 0xefcdab89UL;
    286    md->rmd256.state[2] = 0x98badcfeUL;
    287    md->rmd256.state[3] = 0x10325476UL;
    288    md->rmd256.state[4] = 0x76543210UL;
    289    md->rmd256.state[5] = 0xfedcba98UL;
    290    md->rmd256.state[6] = 0x89abcdefUL;
    291    md->rmd256.state[7] = 0x01234567UL;
    292    md->rmd256.curlen   = 0;
    293    md->rmd256.length   = 0;
    294    return CRYPT_OK;
    295 }
    296 
    297 /**
    298    Process a block of memory though the hash
    299    @param md     The hash state
    300    @param in     The data to hash
    301    @param inlen  The length of the data (octets)
    302    @return CRYPT_OK if successful
    303 */
    304 HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64)
    305 
    306 /**
    307    Terminate the hash to get the digest
    308    @param md  The hash state
    309    @param out [out] The destination of the hash (16 bytes)
    310    @return CRYPT_OK if successful
    311 */
    312 int rmd256_done(hash_state * md, unsigned char *out)
    313 {
    314     int i;
    315 
    316     LTC_ARGCHK(md  != NULL);
    317     LTC_ARGCHK(out != NULL);
    318 
    319     if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) {
    320        return CRYPT_INVALID_ARG;
    321     }
    322 
    323 
    324     /* increase the length of the message */
    325     md->rmd256.length += md->rmd256.curlen * 8;
    326 
    327     /* append the '1' bit */
    328     md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80;
    329 
    330     /* if the length is currently above 56 bytes we append zeros
    331      * then compress.  Then we can fall back to padding zeros and length
    332      * encoding like normal.
    333      */
    334     if (md->rmd256.curlen > 56) {
    335         while (md->rmd256.curlen < 64) {
    336             md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
    337         }
    338         rmd256_compress(md, md->rmd256.buf);
    339         md->rmd256.curlen = 0;
    340     }
    341 
    342     /* pad upto 56 bytes of zeroes */
    343     while (md->rmd256.curlen < 56) {
    344         md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
    345     }
    346 
    347     /* store length */
    348     STORE64L(md->rmd256.length, md->rmd256.buf+56);
    349     rmd256_compress(md, md->rmd256.buf);
    350 
    351     /* copy output */
    352     for (i = 0; i < 8; i++) {
    353         STORE32L(md->rmd256.state[i], out+(4*i));
    354     }
    355 #ifdef LTC_CLEAN_STACK
    356     zeromem(md, sizeof(hash_state));
    357 #endif
    358    return CRYPT_OK;
    359 }
    360 
    361 /**
    362   Self-test the hash
    363   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
    364 */
    365 int rmd256_test(void)
    366 {
    367 #ifndef LTC_TEST
    368    return CRYPT_NOP;
    369 #else
    370    static const struct {
    371         char *msg;
    372         unsigned char md[32];
    373    } tests[] = {
    374    { "",
    375      { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
    376        0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
    377        0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
    378        0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d }
    379    },
    380    { "a",
    381      { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
    382        0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
    383        0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
    384        0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 }
    385    },
    386    { "abc",
    387      { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
    388        0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
    389        0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
    390        0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 }
    391    },
    392    { "message digest",
    393      { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
    394        0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
    395        0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
    396        0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e }
    397    },
    398    { "abcdefghijklmnopqrstuvwxyz",
    399      { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
    400        0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
    401        0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
    402        0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 }
    403    },
    404    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
    405      { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
    406        0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
    407        0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
    408        0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 }
    409    }
    410    };
    411    int x;
    412    unsigned char buf[32];
    413    hash_state md;
    414 
    415    for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
    416        rmd256_init(&md);
    417        rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg));
    418        rmd256_done(&md, buf);
    419        if (XMEMCMP(buf, tests[x].md, 32) != 0) {
    420        #if 0
    421           printf("Failed test %d\n", x);
    422        #endif
    423           return CRYPT_FAIL_TESTVECTOR;
    424        }
    425    }
    426    return CRYPT_OK;
    427 #endif
    428 }
    429 
    430 #endif
    431 
    432