Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ripemd160.c Source File

ripemd160.c

Go to the documentation of this file.
00001 /**
00002  * @file ripemd160.c
00003  * @brief RIPEMD-160 hash function
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneCrypto Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include <string.h>
00034 #include "crypto.h"
00035 #include "ripemd160.h"
00036 
00037 //Check crypto library configuration
00038 #if (RIPEMD160_SUPPORT == ENABLED)
00039 
00040 //RIPEMD-160 auxiliary functions
00041 #define F(x, y, z) ((x) ^ (y) ^ (z))
00042 #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
00043 #define H(x, y, z) (((x) | ~(y)) ^ (z))
00044 #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
00045 #define J(x, y, z) ((x) ^ ((y) | ~(z)))
00046 
00047 #define FF(a, b, c, d, e, x, s) a += F(b, c, d) + (x), a = ROL32(a, s) + (e), c = ROL32(c, 10)
00048 #define GG(a, b, c, d, e, x, s) a += G(b, c, d) + (x) + 0x5A827999, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00049 #define HH(a, b, c, d, e, x, s) a += H(b, c, d) + (x) + 0x6ED9EBA1, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00050 #define II(a, b, c, d, e, x, s) a += I(b, c, d) + (x) + 0x8F1BBCDC, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00051 #define JJ(a, b, c, d, e, x, s) a += J(b, c, d) + (x) + 0xA953FD4E, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00052 
00053 #define FFF(a, b, c, d, e, x, s) a += F(b, c, d) + (x), a = ROL32(a, s) + (e), c = ROL32(c, 10)
00054 #define GGG(a, b, c, d, e, x, s) a += G(b, c, d) + (x) + 0x7A6D76E9, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00055 #define HHH(a, b, c, d, e, x, s) a += H(b, c, d) + (x) + 0x6D703EF3, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00056 #define III(a, b, c, d, e, x, s) a += I(b, c, d) + (x) + 0x5C4DD124, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00057 #define JJJ(a, b, c, d, e, x, s) a += J(b, c, d) + (x) + 0x50A28BE6, a = ROL32(a, s) + (e), c = ROL32(c, 10)
00058 
00059 //RIPEMD-160 padding
00060 static const uint8_t padding[64] =
00061 {
00062    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00063    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00064    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00065    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00066 };
00067 
00068 //RIPEMD-160 object identifier (1.3.36.3.2.1)
00069 static const uint8_t ripemd160Oid[] = {0x2B, 0x24, 0x03, 0x02, 0x01};
00070 
00071 //Common interface for hash algorithms
00072 const HashAlgo ripemd160HashAlgo =
00073 {
00074    "RIPEMD-160",
00075    ripemd160Oid,
00076    sizeof(ripemd160Oid),
00077    sizeof(Ripemd160Context),
00078    RIPEMD160_BLOCK_SIZE,
00079    RIPEMD160_DIGEST_SIZE,
00080    (HashAlgoCompute) ripemd160Compute,
00081    (HashAlgoInit) ripemd160Init,
00082    (HashAlgoUpdate) ripemd160Update,
00083    (HashAlgoFinal) ripemd160Final
00084 };
00085 
00086 
00087 /**
00088  * @brief Digest a message using RIPEMD-160
00089  * @param[in] data Pointer to the message being hashed
00090  * @param[in] length Length of the message
00091  * @param[out] digest Pointer to the calculated digest
00092  * @return Error code
00093  **/
00094 
00095 error_t ripemd160Compute(const void *data, size_t length, uint8_t *digest)
00096 {
00097    //Allocate a memory buffer to hold the RIPEMD-160 context
00098    Ripemd160Context *context = cryptoAllocMem(sizeof(Ripemd160Context));
00099    //Failed to allocate memory?
00100    if(context == NULL)
00101       return ERROR_OUT_OF_MEMORY;
00102 
00103    //Initialize the RIPEMD-160 context
00104    ripemd160Init(context);
00105    //Digest the message
00106    ripemd160Update(context, data, length);
00107    //Finalize the RIPEMD-160 message digest
00108    ripemd160Final(context, digest);
00109 
00110    //Free previously allocated memory
00111    cryptoFreeMem(context);
00112    //Successful processing
00113    return NO_ERROR;
00114 }
00115 
00116 
00117 /**
00118  * @brief Initialize RIPEMD-160 message digest context
00119  * @param[in] context Pointer to the RIPEMD-160 context to initialize
00120  **/
00121 
00122 void ripemd160Init(Ripemd160Context *context)
00123 {
00124    //Set initial hash value
00125    context->h[0] = 0x67452301;
00126    context->h[1] = 0xEFCDAB89;
00127    context->h[2] = 0x98BADCFE;
00128    context->h[3] = 0x10325476;
00129    context->h[4] = 0xC3D2E1F0;
00130 
00131    //Number of bytes in the buffer
00132    context->size = 0;
00133    //Total length of the message
00134    context->totalSize = 0;
00135 }
00136 
00137 
00138 /**
00139  * @brief Update the RIPEMD-160 context with a portion of the message being hashed
00140  * @param[in] context Pointer to the RIPEMD-160 context
00141  * @param[in] data Pointer to the buffer being hashed
00142  * @param[in] length Length of the buffer
00143  **/
00144 
00145 void ripemd160Update(Ripemd160Context *context, const void *data, size_t length)
00146 {
00147    size_t n;
00148 
00149    //Process the incoming data
00150    while(length > 0)
00151    {
00152       //The buffer can hold at most 64 bytes
00153       n = MIN(length, 64 - context->size);
00154 
00155       //Copy the data to the buffer
00156       memcpy(context->buffer + context->size, data, n);
00157 
00158       //Update the RIPEMD-160 context
00159       context->size += n;
00160       context->totalSize += n;
00161       //Advance the data pointer
00162       data = (uint8_t *) data + n;
00163       //Remaining bytes to process
00164       length -= n;
00165 
00166       //Process message in 16-word blocks
00167       if(context->size == 64)
00168       {
00169          //Transform the 16-word block
00170          ripemd160ProcessBlock(context);
00171          //Empty the buffer
00172          context->size = 0;
00173       }
00174    }
00175 }
00176 
00177 
00178 /**
00179  * @brief Finish the RIPEMD-160 message digest
00180  * @param[in] context Pointer to the RIPEMD-160 context
00181  * @param[out] digest Calculated digest (optional parameter)
00182  **/
00183 
00184 void ripemd160Final(Ripemd160Context *context, uint8_t *digest)
00185 {
00186    uint_t i;
00187    size_t paddingSize;
00188    uint64_t totalSize;
00189 
00190    //Length of the original message (before padding)
00191    totalSize = context->totalSize * 8;
00192 
00193    //Pad the message so that its length is congruent to 56 modulo 64
00194    if(context->size < 56)
00195       paddingSize = 56 - context->size;
00196    else
00197       paddingSize = 64 + 56 - context->size;
00198 
00199    //Append padding
00200    ripemd160Update(context, padding, paddingSize);
00201 
00202    //Append the length of the original message
00203    context->x[14] = htole32((uint32_t) totalSize);
00204    context->x[15] = htole32((uint32_t) (totalSize >> 32));
00205 
00206    //Calculate the message digest
00207    ripemd160ProcessBlock(context);
00208 
00209    //Convert from host byte order to little-endian byte order
00210    for(i = 0; i < 4; i++)
00211       context->h[i] = htole32(context->h[i]);
00212 
00213    //Copy the resulting digest
00214    if(digest != NULL)
00215       memcpy(digest, context->digest, RIPEMD160_DIGEST_SIZE);
00216 }
00217 
00218 
00219 /**
00220  * @brief Process message in 16-word blocks
00221  * @param[in] context Pointer to the RIPEMD-160 context
00222  **/
00223 
00224 void ripemd160ProcessBlock(Ripemd160Context *context)
00225 {
00226    uint_t i;
00227 
00228    //Initialize the working registers
00229    uint32_t aa= context->h[0];
00230    uint32_t bb = context->h[1];
00231    uint32_t cc = context->h[2];
00232    uint32_t dd = context->h[3];
00233    uint32_t ee = context->h[4];
00234    uint32_t aaa = context->h[0];
00235    uint32_t bbb = context->h[1];
00236    uint32_t ccc = context->h[2];
00237    uint32_t ddd = context->h[3];
00238    uint32_t eee = context->h[4];
00239 
00240    //Process message in 16-word blocks
00241    uint32_t *x = context->x;
00242 
00243    //Convert from little-endian byte order to host byte order
00244    for(i = 0; i < 16; i++)
00245       x[i] = letoh32(x[i]);
00246 
00247    //Round 1
00248    FF(aa, bb, cc, dd, ee, x[0],  11);
00249    FF(ee, aa, bb, cc, dd, x[1],  14);
00250    FF(dd, ee, aa, bb, cc, x[2],  15);
00251    FF(cc, dd, ee, aa, bb, x[3],  12);
00252    FF(bb, cc, dd, ee, aa, x[4],  5);
00253    FF(aa, bb, cc, dd, ee, x[5],  8);
00254    FF(ee, aa, bb, cc, dd, x[6],  7);
00255    FF(dd, ee, aa, bb, cc, x[7],  9);
00256    FF(cc, dd, ee, aa, bb, x[8],  11);
00257    FF(bb, cc, dd, ee, aa, x[9],  13);
00258    FF(aa, bb, cc, dd, ee, x[10], 14);
00259    FF(ee, aa, bb, cc, dd, x[11], 15);
00260    FF(dd, ee, aa, bb, cc, x[12], 6);
00261    FF(cc, dd, ee, aa, bb, x[13], 7);
00262    FF(bb, cc, dd, ee, aa, x[14], 9);
00263    FF(aa, bb, cc, dd, ee, x[15], 8);
00264 
00265    //Round 2
00266    GG(ee, aa, bb, cc, dd, x[7],  7);
00267    GG(dd, ee, aa, bb, cc, x[4],  6);
00268    GG(cc, dd, ee, aa, bb, x[13], 8);
00269    GG(bb, cc, dd, ee, aa, x[1],  13);
00270    GG(aa, bb, cc, dd, ee, x[10], 11);
00271    GG(ee, aa, bb, cc, dd, x[6],  9);
00272    GG(dd, ee, aa, bb, cc, x[15], 7);
00273    GG(cc, dd, ee, aa, bb, x[3],  15);
00274    GG(bb, cc, dd, ee, aa, x[12], 7);
00275    GG(aa, bb, cc, dd, ee, x[0],  12);
00276    GG(ee, aa, bb, cc, dd, x[9],  15);
00277    GG(dd, ee, aa, bb, cc, x[5],  9);
00278    GG(cc, dd, ee, aa, bb, x[2],  11);
00279    GG(bb, cc, dd, ee, aa, x[14], 7);
00280    GG(aa, bb, cc, dd, ee, x[11], 13);
00281    GG(ee, aa, bb, cc, dd, x[8],  12);
00282 
00283    //Round 3
00284    HH(dd, ee, aa, bb, cc, x[3],  11);
00285    HH(cc, dd, ee, aa, bb, x[10], 13);
00286    HH(bb, cc, dd, ee, aa, x[14], 6);
00287    HH(aa, bb, cc, dd, ee, x[4],  7);
00288    HH(ee, aa, bb, cc, dd, x[9],  14);
00289    HH(dd, ee, aa, bb, cc, x[15], 9);
00290    HH(cc, dd, ee, aa, bb, x[8],  13);
00291    HH(bb, cc, dd, ee, aa, x[1],  15);
00292    HH(aa, bb, cc, dd, ee, x[2],  14);
00293    HH(ee, aa, bb, cc, dd, x[7],  8);
00294    HH(dd, ee, aa, bb, cc, x[0],  13);
00295    HH(cc, dd, ee, aa, bb, x[6],  6);
00296    HH(bb, cc, dd, ee, aa, x[13], 5);
00297    HH(aa, bb, cc, dd, ee, x[11], 12);
00298    HH(ee, aa, bb, cc, dd, x[5],  7);
00299    HH(dd, ee, aa, bb, cc, x[12], 5);
00300 
00301    //Round 4
00302    II(cc, dd, ee, aa, bb, x[1],  11);
00303    II(bb, cc, dd, ee, aa, x[9],  12);
00304    II(aa, bb, cc, dd, ee, x[11], 14);
00305    II(ee, aa, bb, cc, dd, x[10], 15);
00306    II(dd, ee, aa, bb, cc, x[0],  14);
00307    II(cc, dd, ee, aa, bb, x[8],  15);
00308    II(bb, cc, dd, ee, aa, x[12], 9);
00309    II(aa, bb, cc, dd, ee, x[4],  8);
00310    II(ee, aa, bb, cc, dd, x[13], 9);
00311    II(dd, ee, aa, bb, cc, x[3],  14);
00312    II(cc, dd, ee, aa, bb, x[7],  5);
00313    II(bb, cc, dd, ee, aa, x[15], 6);
00314    II(aa, bb, cc, dd, ee, x[14], 8);
00315    II(ee, aa, bb, cc, dd, x[5],  6);
00316    II(dd, ee, aa, bb, cc, x[6],  5);
00317    II(cc, dd, ee, aa, bb, x[2],  12);
00318 
00319    //Round 5
00320    JJ(bb, cc, dd, ee, aa, x[4],  9);
00321    JJ(aa, bb, cc, dd, ee, x[0],  15);
00322    JJ(ee, aa, bb, cc, dd, x[5],  5);
00323    JJ(dd, ee, aa, bb, cc, x[9],  11);
00324    JJ(cc, dd, ee, aa, bb, x[7],  6);
00325    JJ(bb, cc, dd, ee, aa, x[12], 8);
00326    JJ(aa, bb, cc, dd, ee, x[2],  13);
00327    JJ(ee, aa, bb, cc, dd, x[10], 12);
00328    JJ(dd, ee, aa, bb, cc, x[14], 5);
00329    JJ(cc, dd, ee, aa, bb, x[1],  12);
00330    JJ(bb, cc, dd, ee, aa, x[3],  13);
00331    JJ(aa, bb, cc, dd, ee, x[8],  14);
00332    JJ(ee, aa, bb, cc, dd, x[11], 11);
00333    JJ(dd, ee, aa, bb, cc, x[6],  8);
00334    JJ(cc, dd, ee, aa, bb, x[15], 5);
00335    JJ(bb, cc, dd, ee, aa, x[13], 6);
00336 
00337    //Parallel round 1
00338    JJJ(aaa, bbb, ccc, ddd, eee, x[5],  8);
00339    JJJ(eee, aaa, bbb, ccc, ddd, x[14], 9);
00340    JJJ(ddd, eee, aaa, bbb, ccc, x[7],  9);
00341    JJJ(ccc, ddd, eee, aaa, bbb, x[0],  11);
00342    JJJ(bbb, ccc, ddd, eee, aaa, x[9],  13);
00343    JJJ(aaa, bbb, ccc, ddd, eee, x[2],  15);
00344    JJJ(eee, aaa, bbb, ccc, ddd, x[11], 15);
00345    JJJ(ddd, eee, aaa, bbb, ccc, x[4],  5);
00346    JJJ(ccc, ddd, eee, aaa, bbb, x[13], 7);
00347    JJJ(bbb, ccc, ddd, eee, aaa, x[6],  7);
00348    JJJ(aaa, bbb, ccc, ddd, eee, x[15], 8);
00349    JJJ(eee, aaa, bbb, ccc, ddd, x[8],  11);
00350    JJJ(ddd, eee, aaa, bbb, ccc, x[1],  14);
00351    JJJ(ccc, ddd, eee, aaa, bbb, x[10], 14);
00352    JJJ(bbb, ccc, ddd, eee, aaa, x[3],  12);
00353    JJJ(aaa, bbb, ccc, ddd, eee, x[12], 6);
00354 
00355    //Parallel round 2
00356    III(eee, aaa, bbb, ccc, ddd, x[6],   9);
00357    III(ddd, eee, aaa, bbb, ccc, x[11], 13);
00358    III(ccc, ddd, eee, aaa, bbb, x[3],  15);
00359    III(bbb, ccc, ddd, eee, aaa, x[7],  7);
00360    III(aaa, bbb, ccc, ddd, eee, x[0],  12);
00361    III(eee, aaa, bbb, ccc, ddd, x[13], 8);
00362    III(ddd, eee, aaa, bbb, ccc, x[5],  9);
00363    III(ccc, ddd, eee, aaa, bbb, x[10], 11);
00364    III(bbb, ccc, ddd, eee, aaa, x[14], 7);
00365    III(aaa, bbb, ccc, ddd, eee, x[15], 7);
00366    III(eee, aaa, bbb, ccc, ddd, x[8],  12);
00367    III(ddd, eee, aaa, bbb, ccc, x[12], 7);
00368    III(ccc, ddd, eee, aaa, bbb, x[4],  6);
00369    III(bbb, ccc, ddd, eee, aaa, x[9],  15);
00370    III(aaa, bbb, ccc, ddd, eee, x[1],  13);
00371    III(eee, aaa, bbb, ccc, ddd, x[2],  11);
00372 
00373    //Parallel round 3
00374    HHH(ddd, eee, aaa, bbb, ccc, x[15], 9);
00375    HHH(ccc, ddd, eee, aaa, bbb, x[5],  7);
00376    HHH(bbb, ccc, ddd, eee, aaa, x[1],  15);
00377    HHH(aaa, bbb, ccc, ddd, eee, x[3],  11);
00378    HHH(eee, aaa, bbb, ccc, ddd, x[7],  8);
00379    HHH(ddd, eee, aaa, bbb, ccc, x[14], 6);
00380    HHH(ccc, ddd, eee, aaa, bbb, x[6],  6);
00381    HHH(bbb, ccc, ddd, eee, aaa, x[9],  14);
00382    HHH(aaa, bbb, ccc, ddd, eee, x[11], 12);
00383    HHH(eee, aaa, bbb, ccc, ddd, x[8],  13);
00384    HHH(ddd, eee, aaa, bbb, ccc, x[12], 5);
00385    HHH(ccc, ddd, eee, aaa, bbb, x[2],  14);
00386    HHH(bbb, ccc, ddd, eee, aaa, x[10], 13);
00387    HHH(aaa, bbb, ccc, ddd, eee, x[0],  13);
00388    HHH(eee, aaa, bbb, ccc, ddd, x[4],  7);
00389    HHH(ddd, eee, aaa, bbb, ccc, x[13], 5);
00390 
00391    //Parallel round 4
00392    GGG(ccc, ddd, eee, aaa, bbb, x[8],  15);
00393    GGG(bbb, ccc, ddd, eee, aaa, x[6],  5);
00394    GGG(aaa, bbb, ccc, ddd, eee, x[4],  8);
00395    GGG(eee, aaa, bbb, ccc, ddd, x[1],  11);
00396    GGG(ddd, eee, aaa, bbb, ccc, x[3],  14);
00397    GGG(ccc, ddd, eee, aaa, bbb, x[11], 14);
00398    GGG(bbb, ccc, ddd, eee, aaa, x[15], 6);
00399    GGG(aaa, bbb, ccc, ddd, eee, x[0],  14);
00400    GGG(eee, aaa, bbb, ccc, ddd, x[5],  6);
00401    GGG(ddd, eee, aaa, bbb, ccc, x[12], 9);
00402    GGG(ccc, ddd, eee, aaa, bbb, x[2],  12);
00403    GGG(bbb, ccc, ddd, eee, aaa, x[13], 9);
00404    GGG(aaa, bbb, ccc, ddd, eee, x[9],  12);
00405    GGG(eee, aaa, bbb, ccc, ddd, x[7],  5);
00406    GGG(ddd, eee, aaa, bbb, ccc, x[10], 15);
00407    GGG(ccc, ddd, eee, aaa, bbb, x[14], 8);
00408 
00409    //Parallel round 5
00410    FFF(bbb, ccc, ddd, eee, aaa, x[12], 8);
00411    FFF(aaa, bbb, ccc, ddd, eee, x[15], 5);
00412    FFF(eee, aaa, bbb, ccc, ddd, x[10], 12);
00413    FFF(ddd, eee, aaa, bbb, ccc, x[4],  9);
00414    FFF(ccc, ddd, eee, aaa, bbb, x[1],  12);
00415    FFF(bbb, ccc, ddd, eee, aaa, x[5],  5);
00416    FFF(aaa, bbb, ccc, ddd, eee, x[8],  14);
00417    FFF(eee, aaa, bbb, ccc, ddd, x[7],  6);
00418    FFF(ddd, eee, aaa, bbb, ccc, x[6],  8);
00419    FFF(ccc, ddd, eee, aaa, bbb, x[2],  13);
00420    FFF(bbb, ccc, ddd, eee, aaa, x[13], 6);
00421    FFF(aaa, bbb, ccc, ddd, eee, x[14], 5);
00422    FFF(eee, aaa, bbb, ccc, ddd, x[0],  15);
00423    FFF(ddd, eee, aaa, bbb, ccc, x[3],  13);
00424    FFF(ccc, ddd, eee, aaa, bbb, x[9],  11);
00425    FFF(bbb, ccc, ddd, eee, aaa, x[11], 11);
00426 
00427    //Combine results
00428    ddd = context->h[1] + cc + ddd;
00429    context->h[1] = context->h[2] + dd + eee;
00430    context->h[2] = context->h[3] + ee + aaa;
00431    context->h[3] = context->h[4] + aa + bbb;
00432    context->h[4] = context->h[0] + bb + ccc;
00433    context->h[0] = ddd;
00434 }
00435 
00436 #endif
00437