]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/whrlpool/wp_dgst.c
6d925517a26454ff8b461138e56a619207d86527
2 * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * The Whirlpool hashing function.
17 * The Whirlpool algorithm was developed by
18 * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
19 * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
22 * P.S.L.M. Barreto, V. Rijmen,
23 * ``The Whirlpool hashing function,''
24 * NESSIE submission, 2000 (tweaked version, 2001),
25 * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
27 * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
28 * Vincent Rijmen. Lookup "reference implementations" on
29 * <http://planeta.terra.com.br/informatica/paulobarreto/>
31 * =============================================================================
33 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
34 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
37 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
40 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
42 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
43 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 * OpenSSL-specific implementation notes.
50 * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
51 * number of *bytes* as input length argument. Bit-oriented routine
52 * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
53 * does not have one-stroke counterpart.
55 * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
56 * to serve WHIRLPOOL_Update. This is done for performance.
58 * Unlike authors' reference implementation, block processing
59 * routine whirlpool_block is designed to operate on multi-block
60 * input. This is done for performance.
63 #include <openssl/crypto.h>
67 int WHIRLPOOL_Init(WHIRLPOOL_CTX
*c
)
69 memset(c
, 0, sizeof(*c
));
73 int WHIRLPOOL_Update(WHIRLPOOL_CTX
*c
, const void *_inp
, size_t bytes
)
76 * Well, largest suitable chunk size actually is
77 * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not
78 * to care about excessive calls to WHIRLPOOL_BitUpdate...
80 size_t chunk
= ((size_t)1) << (sizeof(size_t) * 8 - 4);
81 const unsigned char *inp
= _inp
;
83 while (bytes
>= chunk
) {
84 WHIRLPOOL_BitUpdate(c
, inp
, chunk
* 8);
89 WHIRLPOOL_BitUpdate(c
, inp
, bytes
* 8);
94 void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX
*c
, const void *_inp
, size_t bits
)
97 unsigned int bitoff
= c
->bitoff
,
98 bitrem
= bitoff
% 8, inpgap
= (8 - (unsigned int)bits
% 8) & 7;
99 const unsigned char *inp
= _inp
;
102 * This 256-bit increment procedure relies on the size_t being natural
103 * size of CPU register, so that we don't have to mask the value in order
104 * to detect overflows.
106 c
->bitlen
[0] += bits
;
107 if (c
->bitlen
[0] < bits
) { /* overflow */
111 } while (c
->bitlen
[n
] == 0
112 && ++n
< (WHIRLPOOL_COUNTER
/ sizeof(size_t)));
114 #ifndef OPENSSL_SMALL_FOOTPRINT
116 if (inpgap
== 0 && bitrem
== 0) { /* byte-oriented loop */
118 if (bitoff
== 0 && (n
= bits
/ WHIRLPOOL_BBLOCK
)) {
119 whirlpool_block(c
, inp
, n
);
120 inp
+= n
* WHIRLPOOL_BBLOCK
/ 8;
121 bits
%= WHIRLPOOL_BBLOCK
;
123 unsigned int byteoff
= bitoff
/ 8;
125 bitrem
= WHIRLPOOL_BBLOCK
- bitoff
; /* re-use bitrem */
126 if (bits
>= bitrem
) {
129 memcpy(c
->data
+ byteoff
, inp
, bitrem
);
131 whirlpool_block(c
, c
->data
, 1);
134 memcpy(c
->data
+ byteoff
, inp
, bits
/ 8);
135 bitoff
+= (unsigned int)bits
;
141 } else /* bit-oriented loop */
147 +-------+-------+-------
148 |||||||||||||||||||||
149 +-------+-------+-------
150 +-------+-------+-------+-------+-------
151 |||||||||||||| c->data
152 +-------+-------+-------+-------+-------
157 unsigned int byteoff
= bitoff
/ 8;
160 #ifndef OPENSSL_SMALL_FOOTPRINT
161 if (bitrem
== inpgap
) {
162 c
->data
[byteoff
++] |= inp
[0] & (0xff >> inpgap
);
165 bitrem
= 0; /* bitoff%8 */
167 inpgap
= 0; /* bits%8 */
169 if (bitoff
== WHIRLPOOL_BBLOCK
) {
170 whirlpool_block(c
, c
->data
, 1);
178 b
= ((inp
[0] << inpgap
) | (inp
[1] >> (8 - inpgap
)));
181 c
->data
[byteoff
++] |= b
>> bitrem
;
183 c
->data
[byteoff
++] = b
;
187 if (bitoff
>= WHIRLPOOL_BBLOCK
) {
188 whirlpool_block(c
, c
->data
, 1);
190 bitoff
%= WHIRLPOOL_BBLOCK
;
193 c
->data
[byteoff
] = b
<< (8 - bitrem
);
194 } else { /* remaining less than or equal to 8 bits */
196 b
= (inp
[0] << inpgap
) & 0xff;
198 c
->data
[byteoff
++] |= b
>> bitrem
;
200 c
->data
[byteoff
++] = b
;
201 bitoff
+= (unsigned int)bits
;
202 if (bitoff
== WHIRLPOOL_BBLOCK
) {
203 whirlpool_block(c
, c
->data
, 1);
205 bitoff
%= WHIRLPOOL_BBLOCK
;
208 c
->data
[byteoff
] = b
<< (8 - bitrem
);
216 int WHIRLPOOL_Final(unsigned char *md
, WHIRLPOOL_CTX
*c
)
218 unsigned int bitoff
= c
->bitoff
, byteoff
= bitoff
/ 8;
224 c
->data
[byteoff
] |= 0x80 >> bitoff
;
226 c
->data
[byteoff
] = 0x80;
230 if (byteoff
> (WHIRLPOOL_BBLOCK
/ 8 - WHIRLPOOL_COUNTER
)) {
231 if (byteoff
< WHIRLPOOL_BBLOCK
/ 8)
232 memset(&c
->data
[byteoff
], 0, WHIRLPOOL_BBLOCK
/ 8 - byteoff
);
233 whirlpool_block(c
, c
->data
, 1);
236 if (byteoff
< (WHIRLPOOL_BBLOCK
/ 8 - WHIRLPOOL_COUNTER
))
237 memset(&c
->data
[byteoff
], 0,
238 (WHIRLPOOL_BBLOCK
/ 8 - WHIRLPOOL_COUNTER
) - byteoff
);
239 /* smash 256-bit c->bitlen in big-endian order */
240 p
= &c
->data
[WHIRLPOOL_BBLOCK
/ 8 - 1]; /* last byte in c->data */
241 for (i
= 0; i
< WHIRLPOOL_COUNTER
/ sizeof(size_t); i
++)
242 for (v
= c
->bitlen
[i
], j
= 0; j
< sizeof(size_t); j
++, v
>>= 8)
243 *p
-- = (unsigned char)(v
& 0xff);
245 whirlpool_block(c
, c
->data
, 1);
248 memcpy(md
, c
->H
.c
, WHIRLPOOL_DIGEST_LENGTH
);
249 OPENSSL_cleanse(c
, sizeof(*c
));
255 unsigned char *WHIRLPOOL(const void *inp
, size_t bytes
, unsigned char *md
)
258 static unsigned char m
[WHIRLPOOL_DIGEST_LENGTH
];
262 WHIRLPOOL_Init(&ctx
);
263 WHIRLPOOL_Update(&ctx
, inp
, bytes
);
264 WHIRLPOOL_Final(md
, &ctx
);