Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:10:15 by
