Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ripemd128.c Source File

ripemd128.c

Go to the documentation of this file.
00001 /**
00002  * @file ripemd128.c
00003  * @brief RIPEMD-128 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 "ripemd128.h"
00036 
00037 //Check crypto library configuration
00038 #if (RIPEMD128_SUPPORT == ENABLED)
00039 
00040 //RIPEMD-128 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 
00046 #define FF(a, b, c, d, x, s) a += F(b, c, d) + (x), a = ROL32(a, s)
00047 #define GG(a, b, c, d, x, s) a += G(b, c, d) + (x) + 0x5A827999, a = ROL32(a, s)
00048 #define HH(a, b, c, d, x, s) a += H(b, c, d) + (x) + 0x6ED9EBA1, a = ROL32(a, s)
00049 #define II(a, b, c, d, x, s) a += I(b, c, d) + (x) + 0x8F1BBCDC, a = ROL32(a, s)
00050 
00051 #define FFF(a, b, c, d, x, s) a += F(b, c, d) + (x), a = ROL32(a, s)
00052 #define GGG(a, b, c, d, x, s) a += G(b, c, d) + (x) + 0x6D703EF3, a = ROL32(a, s)
00053 #define HHH(a, b, c, d, x, s) a += H(b, c, d) + (x) + 0x5C4DD124, a = ROL32(a, s)
00054 #define III(a, b, c, d, x, s) a += I(b, c, d) + (x) + 0x50A28BE6, a = ROL32(a, s)
00055 
00056 //RIPEMD-128 padding
00057 static const uint8_t padding[64] =
00058 {
00059    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00060    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00061    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00062    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00063 };
00064 
00065 //RIPEMD-128 object identifier (1.3.36.3.2.2)
00066 static const uint8_t ripemd128Oid[] = {0x2B, 0x24, 0x03, 0x02, 0x02};
00067 
00068 //Common interface for hash algorithms
00069 const HashAlgo ripemd128HashAlgo =
00070 {
00071    "RIPEMD-128",
00072    ripemd128Oid,
00073    sizeof(ripemd128Oid),
00074    sizeof(Ripemd128Context),
00075    RIPEMD128_BLOCK_SIZE,
00076    RIPEMD128_DIGEST_SIZE,
00077    (HashAlgoCompute) ripemd128Compute,
00078    (HashAlgoInit) ripemd128Init,
00079    (HashAlgoUpdate) ripemd128Update,
00080    (HashAlgoFinal) ripemd128Final
00081 };
00082 
00083 
00084 /**
00085  * @brief Digest a message using RIPEMD-128
00086  * @param[in] data Pointer to the message being hashed
00087  * @param[in] length Length of the message
00088  * @param[out] digest Pointer to the calculated digest
00089  * @return Error code
00090  **/
00091 
00092 error_t ripemd128Compute(const void *data, size_t length, uint8_t *digest)
00093 {
00094    //Allocate a memory buffer to hold the RIPEMD-128 context
00095    Ripemd128Context *context = cryptoAllocMem(sizeof(Ripemd128Context));
00096    //Failed to allocate memory?
00097    if(context == NULL)
00098       return ERROR_OUT_OF_MEMORY;
00099 
00100    //Initialize the RIPEMD-128 context
00101    ripemd128Init(context);
00102    //Digest the message
00103    ripemd128Update(context, data, length);
00104    //Finalize the RIPEMD-128 message digest
00105    ripemd128Final(context, digest);
00106 
00107    //Free previously allocated memory
00108    cryptoFreeMem(context);
00109    //Successful processing
00110    return NO_ERROR;
00111 }
00112 
00113 
00114 /**
00115  * @brief Initialize RIPEMD-128 message digest context
00116  * @param[in] context Pointer to the RIPEMD-128 context to initialize
00117  **/
00118 
00119 void ripemd128Init(Ripemd128Context *context)
00120 {
00121    //Set initial hash value
00122    context->h[0] = 0x67452301;
00123    context->h[1] = 0xEFCDAB89;
00124    context->h[2] = 0x98BADCFE;
00125    context->h[3] = 0x10325476;
00126 
00127    //Number of bytes in the buffer
00128    context->size = 0;
00129    //Total length of the message
00130    context->totalSize = 0;
00131 }
00132 
00133 
00134 /**
00135  * @brief Update the RIPEMD-128 context with a portion of the message being hashed
00136  * @param[in] context Pointer to the RIPEMD-128 context
00137  * @param[in] data Pointer to the buffer being hashed
00138  * @param[in] length Length of the buffer
00139  **/
00140 
00141 void ripemd128Update(Ripemd128Context *context, const void *data, size_t length)
00142 {
00143    size_t n;
00144 
00145    //Process the incoming data
00146    while(length > 0)
00147    {
00148       //The buffer can hold at most 64 bytes
00149       n = MIN(length, 64 - context->size);
00150 
00151       //Copy the data to the buffer
00152       memcpy(context->buffer + context->size, data, n);
00153 
00154       //Update the RIPEMD-128 context
00155       context->size += n;
00156       context->totalSize += n;
00157       //Advance the data pointer
00158       data = (uint8_t *) data + n;
00159       //Remaining bytes to process
00160       length -= n;
00161 
00162       //Process message in 16-word blocks
00163       if(context->size == 64)
00164       {
00165          //Transform the 16-word block
00166          ripemd128ProcessBlock(context);
00167          //Empty the buffer
00168          context->size = 0;
00169       }
00170    }
00171 }
00172 
00173 
00174 /**
00175  * @brief Finish the RIPEMD-128 message digest
00176  * @param[in] context Pointer to the RIPEMD-128 context
00177  * @param[out] digest Calculated digest (optional parameter)
00178  **/
00179 
00180 void ripemd128Final(Ripemd128Context *context, uint8_t *digest)
00181 {
00182    uint_t i;
00183    size_t paddingSize;
00184    uint64_t totalSize;
00185 
00186    //Length of the original message (before padding)
00187    totalSize = context->totalSize * 8;
00188 
00189    //Pad the message so that its length is congruent to 56 modulo 64
00190    if(context->size < 56)
00191       paddingSize = 56 - context->size;
00192    else
00193       paddingSize = 64 + 56 - context->size;
00194 
00195    //Append padding
00196    ripemd128Update(context, padding, paddingSize);
00197 
00198    //Append the length of the original message
00199    context->x[14] = htole32((uint32_t) totalSize);
00200    context->x[15] = htole32((uint32_t) (totalSize >> 32));
00201 
00202    //Calculate the message digest
00203    ripemd128ProcessBlock(context);
00204 
00205    //Convert from host byte order to little-endian byte order
00206    for(i = 0; i < 4; i++)
00207       context->h[i] = htole32(context->h[i]);
00208 
00209    //Copy the resulting digest
00210    if(digest != NULL)
00211       memcpy(digest, context->digest, RIPEMD128_DIGEST_SIZE);
00212 }
00213 
00214 
00215 /**
00216  * @brief Process message in 16-word blocks
00217  * @param[in] context Pointer to the RIPEMD-128 context
00218  **/
00219 
00220 void ripemd128ProcessBlock(Ripemd128Context *context)
00221 {
00222    uint_t i;
00223 
00224    //Initialize the working registers
00225    uint32_t aa= context->h[0];
00226    uint32_t bb = context->h[1];
00227    uint32_t cc = context->h[2];
00228    uint32_t dd = context->h[3];
00229    uint32_t aaa = context->h[0];
00230    uint32_t bbb = context->h[1];
00231    uint32_t ccc = context->h[2];
00232    uint32_t ddd = context->h[3];
00233 
00234    //Process message in 16-word blocks
00235    uint32_t *x = context->x;
00236 
00237    //Convert from little-endian byte order to host byte order
00238    for(i = 0; i < 16; i++)
00239       x[i] = letoh32(x[i]);
00240 
00241    //Round 1
00242    FF(aa, bb, cc, dd, x[0],  11);
00243    FF(dd, aa, bb, cc, x[1],  14);
00244    FF(cc, dd, aa, bb, x[2],  15);
00245    FF(bb, cc, dd, aa, x[3],  12);
00246    FF(aa, bb, cc, dd, x[4],  5);
00247    FF(dd, aa, bb, cc, x[5],  8);
00248    FF(cc, dd, aa, bb, x[6],  7);
00249    FF(bb, cc, dd, aa, x[7],  9);
00250    FF(aa, bb, cc, dd, x[8],  11);
00251    FF(dd, aa, bb, cc, x[9],  13);
00252    FF(cc, dd, aa, bb, x[10], 14);
00253    FF(bb, cc, dd, aa, x[11], 15);
00254    FF(aa, bb, cc, dd, x[12], 6);
00255    FF(dd, aa, bb, cc, x[13], 7);
00256    FF(cc, dd, aa, bb, x[14], 9);
00257    FF(bb, cc, dd, aa, x[15], 8);
00258 
00259    //Round 2
00260    GG(aa, bb, cc, dd, x[7],  7);
00261    GG(dd, aa, bb, cc, x[4],  6);
00262    GG(cc, dd, aa, bb, x[13], 8);
00263    GG(bb, cc, dd, aa, x[1],  13);
00264    GG(aa, bb, cc, dd, x[10], 11);
00265    GG(dd, aa, bb, cc, x[6],  9);
00266    GG(cc, dd, aa, bb, x[15], 7);
00267    GG(bb, cc, dd, aa, x[3],  15);
00268    GG(aa, bb, cc, dd, x[12], 7);
00269    GG(dd, aa, bb, cc, x[0],  12);
00270    GG(cc, dd, aa, bb, x[9],  15);
00271    GG(bb, cc, dd, aa, x[5],  9);
00272    GG(aa, bb, cc, dd, x[2],  11);
00273    GG(dd, aa, bb, cc, x[14], 7);
00274    GG(cc, dd, aa, bb, x[11], 13);
00275    GG(bb, cc, dd, aa, x[8],  12);
00276 
00277    //Round 3
00278    HH(aa, bb, cc, dd, x[3],  11);
00279    HH(dd, aa, bb, cc, x[10], 13);
00280    HH(cc, dd, aa, bb, x[14], 6);
00281    HH(bb, cc, dd, aa, x[4],  7);
00282    HH(aa, bb, cc, dd, x[9],  14);
00283    HH(dd, aa, bb, cc, x[15], 9);
00284    HH(cc, dd, aa, bb, x[8],  13);
00285    HH(bb, cc, dd, aa, x[1],  15);
00286    HH(aa, bb, cc, dd, x[2],  14);
00287    HH(dd, aa, bb, cc, x[7],  8);
00288    HH(cc, dd, aa, bb, x[0],  13);
00289    HH(bb, cc, dd, aa, x[6],  6);
00290    HH(aa, bb, cc, dd, x[13], 5);
00291    HH(dd, aa, bb, cc, x[11], 12);
00292    HH(cc, dd, aa, bb, x[5],  7);
00293    HH(bb, cc, dd, aa, x[12], 5);
00294 
00295    //Round 4
00296    II(aa, bb, cc, dd, x[1],  11);
00297    II(dd, aa, bb, cc, x[9],  12);
00298    II(cc, dd, aa, bb, x[11], 14);
00299    II(bb, cc, dd, aa, x[10], 15);
00300    II(aa, bb, cc, dd, x[0],  14);
00301    II(dd, aa, bb, cc, x[8],  15);
00302    II(cc, dd, aa, bb, x[12], 9);
00303    II(bb, cc, dd, aa, x[4],  8);
00304    II(aa, bb, cc, dd, x[13], 9);
00305    II(dd, aa, bb, cc, x[3],  14);
00306    II(cc, dd, aa, bb, x[7],  5);
00307    II(bb, cc, dd, aa, x[15], 6);
00308    II(aa, bb, cc, dd, x[14], 8);
00309    II(dd, aa, bb, cc, x[5],  6);
00310    II(cc, dd, aa, bb, x[6],  5);
00311    II(bb, cc, dd, aa, x[2],  12);
00312 
00313    //Parallel round 1
00314    III(aaa, bbb, ccc, ddd, x[5],  8);
00315    III(ddd, aaa, bbb, ccc, x[14], 9);
00316    III(ccc, ddd, aaa, bbb, x[7],  9);
00317    III(bbb, ccc, ddd, aaa, x[0],  11);
00318    III(aaa, bbb, ccc, ddd, x[9],  13);
00319    III(ddd, aaa, bbb, ccc, x[2],  15);
00320    III(ccc, ddd, aaa, bbb, x[11], 15);
00321    III(bbb, ccc, ddd, aaa, x[4],  5);
00322    III(aaa, bbb, ccc, ddd, x[13], 7);
00323    III(ddd, aaa, bbb, ccc, x[6],  7);
00324    III(ccc, ddd, aaa, bbb, x[15], 8);
00325    III(bbb, ccc, ddd, aaa, x[8],  11);
00326    III(aaa, bbb, ccc, ddd, x[1],  14);
00327    III(ddd, aaa, bbb, ccc, x[10], 14);
00328    III(ccc, ddd, aaa, bbb, x[3],  12);
00329    III(bbb, ccc, ddd, aaa, x[12], 6);
00330 
00331    //Parallel round 2
00332    HHH(aaa, bbb, ccc, ddd, x[6],  9);
00333    HHH(ddd, aaa, bbb, ccc, x[11], 13);
00334    HHH(ccc, ddd, aaa, bbb, x[3],  15);
00335    HHH(bbb, ccc, ddd, aaa, x[7],  7);
00336    HHH(aaa, bbb, ccc, ddd, x[0],  12);
00337    HHH(ddd, aaa, bbb, ccc, x[13], 8);
00338    HHH(ccc, ddd, aaa, bbb, x[5],  9);
00339    HHH(bbb, ccc, ddd, aaa, x[10], 11);
00340    HHH(aaa, bbb, ccc, ddd, x[14], 7);
00341    HHH(ddd, aaa, bbb, ccc, x[15], 7);
00342    HHH(ccc, ddd, aaa, bbb, x[8],  12);
00343    HHH(bbb, ccc, ddd, aaa, x[12], 7);
00344    HHH(aaa, bbb, ccc, ddd, x[4],  6);
00345    HHH(ddd, aaa, bbb, ccc, x[9],  15);
00346    HHH(ccc, ddd, aaa, bbb, x[1],  13);
00347    HHH(bbb, ccc, ddd, aaa, x[2],  11);
00348 
00349    //Parallel round 3
00350    GGG(aaa, bbb, ccc, ddd, x[15], 9);
00351    GGG(ddd, aaa, bbb, ccc, x[5],  7);
00352    GGG(ccc, ddd, aaa, bbb, x[1],  15);
00353    GGG(bbb, ccc, ddd, aaa, x[3],  11);
00354    GGG(aaa, bbb, ccc, ddd, x[7],  8);
00355    GGG(ddd, aaa, bbb, ccc, x[14], 6);
00356    GGG(ccc, ddd, aaa, bbb, x[6],  6);
00357    GGG(bbb, ccc, ddd, aaa, x[9],  14);
00358    GGG(aaa, bbb, ccc, ddd, x[11], 12);
00359    GGG(ddd, aaa, bbb, ccc, x[8],  13);
00360    GGG(ccc, ddd, aaa, bbb, x[12], 5);
00361    GGG(bbb, ccc, ddd, aaa, x[2],  14);
00362    GGG(aaa, bbb, ccc, ddd, x[10], 13);
00363    GGG(ddd, aaa, bbb, ccc, x[0],  13);
00364    GGG(ccc, ddd, aaa, bbb, x[4],  7);
00365    GGG(bbb, ccc, ddd, aaa, x[13], 5);
00366 
00367    //Parallel round 4
00368    FFF(aaa, bbb, ccc, ddd, x[8],  15);
00369    FFF(ddd, aaa, bbb, ccc, x[6],  5);
00370    FFF(ccc, ddd, aaa, bbb, x[4],  8);
00371    FFF(bbb, ccc, ddd, aaa, x[1],  11);
00372    FFF(aaa, bbb, ccc, ddd, x[3],  14);
00373    FFF(ddd, aaa, bbb, ccc, x[11], 14);
00374    FFF(ccc, ddd, aaa, bbb, x[15], 6);
00375    FFF(bbb, ccc, ddd, aaa, x[0],  14);
00376    FFF(aaa, bbb, ccc, ddd, x[5],  6);
00377    FFF(ddd, aaa, bbb, ccc, x[12], 9);
00378    FFF(ccc, ddd, aaa, bbb, x[2],  12);
00379    FFF(bbb, ccc, ddd, aaa, x[13], 9);
00380    FFF(aaa, bbb, ccc, ddd, x[9],  12);
00381    FFF(ddd, aaa, bbb, ccc, x[7],  5);
00382    FFF(ccc, ddd, aaa, bbb, x[10], 15);
00383    FFF(bbb, ccc, ddd, aaa, x[14], 8);
00384 
00385    //Combine results
00386    ddd = context->h[1] + cc + ddd;
00387    context->h[1] = context->h[2] + dd + aaa;
00388    context->h[2] = context->h[3] + aa + bbb;
00389    context->h[3] = context->h[0] + bb + ccc;
00390    context->h[0] = ddd;
00391 }
00392 
00393 #endif
00394