whirlpool.c
Go to the documentation of this file.
1 /**
2  * @file whirlpool.c
3  * @brief Whirlpool hash function
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * Whirlpool is a hash function that operates on messages less than 2^256 bits
30  * in length, and produces a message digest of 512 bits
31  *
32  * @author Oryx Embedded SARL (www.oryx-embedded.com)
33  * @version 2.4.4
34  **/
35 
36 //Switch to the appropriate trace level
37 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
38 
39 //Dependencies
40 #include "core/crypto.h"
41 #include "hash/whirlpool.h"
42 
43 //Check crypto library configuration
44 #if (WHIRLPOOL_SUPPORT == ENABLED)
45 
46 //Round function
47 #define RHO(b, a, n, c) \
48 { \
49  b = t[(a[n] >> 56) & 0xFF]; \
50  b ^= ROR64(t[(a[(n + 7) % 8] >> 48) & 0xFF], 8); \
51  b ^= ROR64(t[(a[(n + 6) % 8] >> 40) & 0xFF], 16); \
52  b ^= ROR64(t[(a[(n + 5) % 8] >> 32) & 0xFF], 24); \
53  b ^= ROR64(t[(a[(n + 4) % 8] >> 24) & 0xFF], 32); \
54  b ^= ROR64(t[(a[(n + 3) % 8] >> 16) & 0xFF], 40); \
55  b ^= ROR64(t[(a[(n + 2) % 8] >> 8) & 0xFF], 48); \
56  b ^= ROR64(t[a[(n + 1) % 8] & 0xFF], 56); \
57  b ^= c; \
58 }
59 
60 //Whirlpool padding
61 static const uint8_t padding[64] =
62 {
63  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
67 };
68 
69 //Whirlpool constants
70 static const uint64_t rc[10] =
71 {
72  0x1823C6E887B8014F,
73  0x36A6D2F5796F9152,
74  0x60BC9B8EA30C7B35,
75  0x1DE0D7C22E4BFE57,
76  0x157737E59FF04ADA,
77  0x58C9290AB1A06B85,
78  0xBD5D10F4CB3E0567,
79  0xE427418BA77D95D8,
80  0xFBEE7C66DD17479E,
81  0xCA2DBF07AD5A8333
82 };
83 
84 //Whirlpool look-up table
85 static const uint64_t t[256] =
86 {
87  0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB,
88  0x878726874CA113CB, 0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D,
89  0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF, 0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E,
90  0x7979F979EF80F296, 0x6F6FA16F5FCEDE30, 0x91917E91FCEF3F6D, 0x52525552AA07A4F8,
91  0x60609D6027FDC047, 0xBCBCCABC89766535, 0x9B9B569BACCD2B37, 0x8E8E028E048C018A,
92  0xA3A3B6A371155BD2, 0x0C0C300C603C186C, 0x7B7BF17BFF8AF684, 0x3535D435B5E16A80,
93  0x1D1D741DE8693AF5, 0xE0E0A7E05347DDB3, 0xD7D77BD7F6ACB321, 0xC2C22FC25EED999C,
94  0x2E2EB82E6D965C43, 0x4B4B314B627A9629, 0xFEFEDFFEA321E15D, 0x575741578216AED5,
95  0x15155415A8412ABD, 0x7777C1779FB6EEE8, 0x3737DC37A5EB6E92, 0xE5E5B3E57B56D79E,
96  0x9F9F469F8CD92313, 0xF0F0E7F0D317FD23, 0x4A4A354A6A7F9420, 0xDADA4FDA9E95A944,
97  0x58587D58FA25B0A2, 0xC9C903C906CA8FCF, 0x2929A429558D527C, 0x0A0A280A5022145A,
98  0xB1B1FEB1E14F7F50, 0xA0A0BAA0691A5DC9, 0x6B6BB16B7FDAD614, 0x85852E855CAB17D9,
99  0xBDBDCEBD8173673C, 0x5D5D695DD234BA8F, 0x1010401080502090, 0xF4F4F7F4F303F507,
100  0xCBCB0BCB16C08BDD, 0x3E3EF83EEDC67CD3, 0x0505140528110A2D, 0x676781671FE6CE78,
101  0xE4E4B7E47353D597, 0x27279C2725BB4E02, 0x4141194132588273, 0x8B8B168B2C9D0BA7,
102  0xA7A7A6A7510153F6, 0x7D7DE97DCF94FAB2, 0x95956E95DCFB3749, 0xD8D847D88E9FAD56,
103  0xFBFBCBFB8B30EB70, 0xEEEE9FEE2371C1CD, 0x7C7CED7CC791F8BB, 0x6666856617E3CC71,
104  0xDDDD53DDA68EA77B, 0x17175C17B84B2EAF, 0x4747014702468E45, 0x9E9E429E84DC211A,
105  0xCACA0FCA1EC589D4, 0x2D2DB42D75995A58, 0xBFBFC6BF9179632E, 0x07071C07381B0E3F,
106  0xADAD8EAD012347AC, 0x5A5A755AEA2FB4B0, 0x838336836CB51BEF, 0x3333CC3385FF66B6,
107  0x636391633FF2C65C, 0x02020802100A0412, 0xAAAA92AA39384993, 0x7171D971AFA8E2DE,
108  0xC8C807C80ECF8DC6, 0x19196419C87D32D1, 0x494939497270923B, 0xD9D943D9869AAF5F,
109  0xF2F2EFF2C31DF931, 0xE3E3ABE34B48DBA8, 0x5B5B715BE22AB6B9, 0x88881A8834920DBC,
110  0x9A9A529AA4C8293E, 0x262698262DBE4C0B, 0x3232C8328DFA64BF, 0xB0B0FAB0E94A7D59,
111  0xE9E983E91B6ACFF2, 0x0F0F3C0F78331E77, 0xD5D573D5E6A6B733, 0x80803A8074BA1DF4,
112  0xBEBEC2BE997C6127, 0xCDCD13CD26DE87EB, 0x3434D034BDE46889, 0x48483D487A759032,
113  0xFFFFDBFFAB24E354, 0x7A7AF57AF78FF48D, 0x90907A90F4EA3D64, 0x5F5F615FC23EBE9D,
114  0x202080201DA0403D, 0x6868BD6867D5D00F, 0x1A1A681AD07234CA, 0xAEAE82AE192C41B7,
115  0xB4B4EAB4C95E757D, 0x54544D549A19A8CE, 0x93937693ECE53B7F, 0x222288220DAA442F,
116  0x64648D6407E9C863, 0xF1F1E3F1DB12FF2A, 0x7373D173BFA2E6CC, 0x12124812905A2482,
117  0x40401D403A5D807A, 0x0808200840281048, 0xC3C32BC356E89B95, 0xECEC97EC337BC5DF,
118  0xDBDB4BDB9690AB4D, 0xA1A1BEA1611F5FC0, 0x8D8D0E8D1C830791, 0x3D3DF43DF5C97AC8,
119  0x97976697CCF1335B, 0x0000000000000000, 0xCFCF1BCF36D483F9, 0x2B2BAC2B4587566E,
120  0x7676C57697B3ECE1, 0x8282328264B019E6, 0xD6D67FD6FEA9B128, 0x1B1B6C1BD87736C3,
121  0xB5B5EEB5C15B7774, 0xAFAF86AF112943BE, 0x6A6AB56A77DFD41D, 0x50505D50BA0DA0EA,
122  0x45450945124C8A57, 0xF3F3EBF3CB18FB38, 0x3030C0309DF060AD, 0xEFEF9BEF2B74C3C4,
123  0x3F3FFC3FE5C37EDA, 0x55554955921CAAC7, 0xA2A2B2A2791059DB, 0xEAEA8FEA0365C9E9,
124  0x656589650FECCA6A, 0xBABAD2BAB9686903, 0x2F2FBC2F65935E4A, 0xC0C027C04EE79D8E,
125  0xDEDE5FDEBE81A160, 0x1C1C701CE06C38FC, 0xFDFDD3FDBB2EE746, 0x4D4D294D52649A1F,
126  0x92927292E4E03976, 0x7575C9758FBCEAFA, 0x06061806301E0C36, 0x8A8A128A249809AE,
127  0xB2B2F2B2F940794B, 0xE6E6BFE66359D185, 0x0E0E380E70361C7E, 0x1F1F7C1FF8633EE7,
128  0x6262956237F7C455, 0xD4D477D4EEA3B53A, 0xA8A89AA829324D81, 0x96966296C4F43152,
129  0xF9F9C3F99B3AEF62, 0xC5C533C566F697A3, 0x2525942535B14A10, 0x59597959F220B2AB,
130  0x84842A8454AE15D0, 0x7272D572B7A7E4C5, 0x3939E439D5DD72EC, 0x4C4C2D4C5A619816,
131  0x5E5E655ECA3BBC94, 0x7878FD78E785F09F, 0x3838E038DDD870E5, 0x8C8C0A8C14860598,
132  0xD1D163D1C6B2BF17, 0xA5A5AEA5410B57E4, 0xE2E2AFE2434DD9A1, 0x616199612FF8C24E,
133  0xB3B3F6B3F1457B42, 0x2121842115A54234, 0x9C9C4A9C94D62508, 0x1E1E781EF0663CEE,
134  0x4343114322528661, 0xC7C73BC776FC93B1, 0xFCFCD7FCB32BE54F, 0x0404100420140824,
135  0x51515951B208A2E3, 0x99995E99BCC72F25, 0x6D6DA96D4FC4DA22, 0x0D0D340D68391A65,
136  0xFAFACFFA8335E979, 0xDFDF5BDFB684A369, 0x7E7EE57ED79BFCA9, 0x242490243DB44819,
137  0x3B3BEC3BC5D776FE, 0xABAB96AB313D4B9A, 0xCECE1FCE3ED181F0, 0x1111441188552299,
138  0x8F8F068F0C890383, 0x4E4E254E4A6B9C04, 0xB7B7E6B7D1517366, 0xEBEB8BEB0B60CBE0,
139  0x3C3CF03CFDCC78C1, 0x81813E817CBF1FFD, 0x94946A94D4FE3540, 0xF7F7FBF7EB0CF31C,
140  0xB9B9DEB9A1676F18, 0x13134C13985F268B, 0x2C2CB02C7D9C5851, 0xD3D36BD3D6B8BB05,
141  0xE7E7BBE76B5CD38C, 0x6E6EA56E57CBDC39, 0xC4C437C46EF395AA, 0x03030C03180F061B,
142  0x565645568A13ACDC, 0x44440D441A49885E, 0x7F7FE17FDF9EFEA0, 0xA9A99EA921374F88,
143  0x2A2AA82A4D825467, 0xBBBBD6BBB16D6B0A, 0xC1C123C146E29F87, 0x53535153A202A6F1,
144  0xDCDC57DCAE8BA572, 0x0B0B2C0B58271653, 0x9D9D4E9D9CD32701, 0x6C6CAD6C47C1D82B,
145  0x3131C43195F562A4, 0x7474CD7487B9E8F3, 0xF6F6FFF6E309F115, 0x464605460A438C4C,
146  0xACAC8AAC092645A5, 0x89891E893C970FB5, 0x14145014A04428B4, 0xE1E1A3E15B42DFBA,
147  0x16165816B04E2CA6, 0x3A3AE83ACDD274F7, 0x6969B9696FD0D206, 0x09092409482D1241,
148  0x7070DD70A7ADE0D7, 0xB6B6E2B6D954716F, 0xD0D067D0CEB7BD1E, 0xEDED93ED3B7EC7D6,
149  0xCCCC17CC2EDB85E2, 0x424215422A578468, 0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED,
150  0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B, 0x8686228644A411C2
151 };
152 
153 //Whirlpool object identifier (1.0.10118.3.0.55)
154 const uint8_t WHIRLPOOL_OID[6] = {0x28, 0xCF, 0x06, 0x03, 0x00, 0x37};
155 
156 //Common interface for hash algorithms
158 {
159  "Whirlpool",
161  sizeof(WHIRLPOOL_OID),
162  sizeof(WhirlpoolContext),
166  TRUE,
171  NULL
172 };
173 
174 
175 /**
176  * @brief Digest a message using Whirlpool
177  * @param[in] data Pointer to the message being hashed
178  * @param[in] length Length of the message
179  * @param[out] digest Pointer to the calculated digest
180  * @return Error code
181  **/
182 
183 error_t whirlpoolCompute(const void *data, size_t length, uint8_t *digest)
184 {
185 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
186  WhirlpoolContext *context;
187 #else
188  WhirlpoolContext context[1];
189 #endif
190 
191  //Check parameters
192  if(data == NULL && length != 0)
194 
195  if(digest == NULL)
197 
198 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
199  //Allocate a memory buffer to hold the Whirlpool context
200  context = cryptoAllocMem(sizeof(WhirlpoolContext));
201  //Failed to allocate memory?
202  if(context == NULL)
203  return ERROR_OUT_OF_MEMORY;
204 #endif
205 
206  //Initialize the Whirlpool context
207  whirlpoolInit(context);
208  //Digest the message
209  whirlpoolUpdate(context, data, length);
210  //Finalize the Whirlpool message digest
211  whirlpoolFinal(context, digest);
212 
213 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
214  //Free previously allocated memory
215  cryptoFreeMem(context);
216 #endif
217 
218  //Successful operation
219  return NO_ERROR;
220 }
221 
222 
223 /**
224  * @brief Initialize Whirlpool message digest context
225  * @param[in] context Pointer to the Whirlpool context to initialize
226  **/
227 
229 {
230  uint_t i;
231 
232  //Set initial hash value
233  for(i = 0; i < 8; i++)
234  {
235  context->h[i] = 0;
236  }
237 
238  //Number of bytes in the buffer
239  context->size = 0;
240  //Total length of the message
241  context->totalSize = 0;
242 }
243 
244 
245 /**
246  * @brief Update the Whirlpool context with a portion of the message being hashed
247  * @param[in] context Pointer to the Whirlpool context
248  * @param[in] data Pointer to the buffer being hashed
249  * @param[in] length Length of the buffer
250  **/
251 
252 void whirlpoolUpdate(WhirlpoolContext *context, const void *data, size_t length)
253 {
254  size_t n;
255 
256  //Process the incoming data
257  while(length > 0)
258  {
259  //The buffer can hold at most 64 bytes
260  n = MIN(length, 64 - context->size);
261 
262  //Copy the data to the buffer
263  osMemcpy(context->buffer + context->size, data, n);
264 
265  //Update the Whirlpool context
266  context->size += n;
267  context->totalSize += n;
268  //Advance the data pointer
269  data = (uint8_t *) data + n;
270  //Remaining bytes to process
271  length -= n;
272 
273  //Process message in 8-word blocks
274  if(context->size == 64)
275  {
276  //Transform the 8-word block
277  whirlpoolProcessBlock(context);
278  //Empty the buffer
279  context->size = 0;
280  }
281  }
282 }
283 
284 
285 /**
286  * @brief Finish the Whirlpool message digest
287  * @param[in] context Pointer to the Whirlpool context
288  * @param[out] digest Calculated digest (optional parameter)
289  **/
290 
291 void whirlpoolFinal(WhirlpoolContext *context, uint8_t *digest)
292 {
293  uint_t i;
294  size_t paddingSize;
295  uint64_t totalSize;
296 
297  //Length of the original message (before padding)
298  totalSize = context->totalSize * 8;
299 
300  //Pad the message so that its length is congruent to 32 modulo 64
301  if(context->size < 32)
302  {
303  paddingSize = 32 - context->size;
304  }
305  else
306  {
307  paddingSize = 64 + 32 - context->size;
308  }
309 
310  //Append padding
311  whirlpoolUpdate(context, padding, paddingSize);
312 
313  //Append the length of the original message
314  context->x[4] = 0;
315  context->x[5] = 0;
316  context->x[6] = 0;
317  context->x[7] = htobe64(totalSize);
318 
319  //Calculate the message digest
320  whirlpoolProcessBlock(context);
321 
322  //Convert from host byte order to big-endian byte order
323  for(i = 0; i < 8; i++)
324  {
325  context->h[i] = htobe64(context->h[i]);
326  }
327 
328  //Copy the resulting digest
329  if(digest != NULL)
330  {
331  osMemcpy(digest, context->digest, WHIRLPOOL_DIGEST_SIZE);
332  }
333 }
334 
335 
336 /**
337  * @brief Process message in 16-word blocks
338  * @param[in] context Pointer to the Whirlpool context
339  **/
340 
342 {
343  uint_t i;
344 
345  uint64_t *x = context->x;
346  uint64_t *k = context->k;
347  uint64_t *l = context->l;
348  uint64_t *state = context->state;
349 
350  //Convert from big-endian byte order to host byte order
351  for(i = 0; i < 8; i++)
352  {
353  x[i] = betoh64(x[i]);
354  }
355 
356  k[0] = context->h[0];
357  k[1] = context->h[1];
358  k[2] = context->h[2];
359  k[3] = context->h[3];
360  k[4] = context->h[4];
361  k[5] = context->h[5];
362  k[6] = context->h[6];
363  k[7] = context->h[7];
364 
365  state[0] = x[0] ^ k[0];
366  state[1] = x[1] ^ k[1];
367  state[2] = x[2] ^ k[2];
368  state[3] = x[3] ^ k[3];
369  state[4] = x[4] ^ k[4];
370  state[5] = x[5] ^ k[5];
371  state[6] = x[6] ^ k[6];
372  state[7] = x[7] ^ k[7];
373 
374  //Iterate over all rounds
375  for(i = 0; i < 10; i++)
376  {
377  //Key schedule
378  RHO(l[0], k, 0, rc[i]);
379  RHO(l[1], k, 1, 0);
380  RHO(l[2], k, 2, 0);
381  RHO(l[3], k, 3, 0);
382  RHO(l[4], k, 4, 0);
383  RHO(l[5], k, 5, 0);
384  RHO(l[6], k, 6, 0);
385  RHO(l[7], k, 7, 0);
386 
387  k[0] = l[0];
388  k[1] = l[1];
389  k[2] = l[2];
390  k[3] = l[3];
391  k[4] = l[4];
392  k[5] = l[5];
393  k[6] = l[6];
394  k[7] = l[7];
395 
396  //Apply the round function
397  RHO(l[0], state, 0, k[0]);
398  RHO(l[1], state, 1, k[1]);
399  RHO(l[2], state, 2, k[2]);
400  RHO(l[3], state, 3, k[3]);
401  RHO(l[4], state, 4, k[4]);
402  RHO(l[5], state, 5, k[5]);
403  RHO(l[6], state, 6, k[6]);
404  RHO(l[7], state, 7, k[7]);
405 
406  state[0] = l[0];
407  state[1] = l[1];
408  state[2] = l[2];
409  state[3] = l[3];
410  state[4] = l[4];
411  state[5] = l[5];
412  state[6] = l[6];
413  state[7] = l[7];
414  }
415 
416  //Update the hash value
417  context->h[0] ^= state[0] ^ x[0];
418  context->h[1] ^= state[1] ^ x[1];
419  context->h[2] ^= state[2] ^ x[2];
420  context->h[3] ^= state[3] ^ x[3];
421  context->h[4] ^= state[4] ^ x[4];
422  context->h[5] ^= state[5] ^ x[5];
423  context->h[6] ^= state[6] ^ x[6];
424  context->h[7] ^= state[7] ^ x[7];
425 }
426 
427 #endif
void whirlpoolUpdate(WhirlpoolContext *context, const void *data, size_t length)
Update the Whirlpool context with a portion of the message being hashed.
Definition: whirlpool.c:252
uint64_t k[8]
Definition: whirlpool.h:69
#define WHIRLPOOL_MIN_PAD_SIZE
Definition: whirlpool.h:42
void(* HashAlgoInit)(void *context)
Definition: crypto.h:991
const uint8_t WHIRLPOOL_OID[6]
Definition: whirlpool.c:154
#define WHIRLPOOL_BLOCK_SIZE
Definition: whirlpool.h:38
uint8_t digest[64]
Definition: whirlpool.h:61
uint8_t x
Definition: lldp_ext_med.h:211
uint64_t h[8]
Definition: whirlpool.h:60
uint8_t t
Definition: lldp_ext_med.h:212
#define TRUE
Definition: os_port.h:50
#define RHO(b, a, n, c)
Definition: whirlpool.c:47
uint8_t data[]
Definition: ethernet.h:222
uint8_t buffer[64]
Definition: whirlpool.h:66
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
const HashAlgo whirlpoolHashAlgo
Definition: whirlpool.c:157
void whirlpoolProcessBlock(WhirlpoolContext *context)
Process message in 16-word blocks.
Definition: whirlpool.c:341
void(* HashAlgoUpdate)(void *context, const void *data, size_t length)
Definition: crypto.h:993
uint64_t totalSize
Definition: whirlpool.h:74
uint64_t l[8]
Definition: whirlpool.h:70
void whirlpoolInit(WhirlpoolContext *context)
Initialize Whirlpool message digest context.
Definition: whirlpool.c:228
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
uint64_t x[8]
Definition: whirlpool.h:65
General definitions for cryptographic algorithms.
#define htobe64(value)
Definition: cpu_endian.h:447
uint8_t length
Definition: tcp.h:368
#define MIN(a, b)
Definition: os_port.h:63
uint64_t state[8]
Definition: whirlpool.h:71
void whirlpoolFinal(WhirlpoolContext *context, uint8_t *digest)
Finish the Whirlpool message digest.
Definition: whirlpool.c:291
Whirlpool algorithm context.
Definition: whirlpool.h:57
void(* HashAlgoFinal)(void *context, uint8_t *digest)
Definition: crypto.h:995
uint8_t l
Definition: ndp.h:412
uint8_t n
#define betoh64(value)
Definition: cpu_endian.h:455
#define cryptoFreeMem(p)
Definition: crypto.h:791
#define cryptoAllocMem(size)
Definition: crypto.h:786
Common interface for hash algorithms.
Definition: crypto.h:1046
Whirlpool hash function.
error_t whirlpoolCompute(const void *data, size_t length, uint8_t *digest)
Digest a message using Whirlpool.
Definition: whirlpool.c:183
unsigned int uint_t
Definition: compiler_port.h:50
#define WHIRLPOOL_DIGEST_SIZE
Definition: whirlpool.h:40
error_t(* HashAlgoCompute)(const void *data, size_t length, uint8_t *digest)
Definition: crypto.h:988
@ NO_ERROR
Success.
Definition: error.h:44