1 /* ===================================================================
2  *
3  * Copyright (c) 2014, Legrandin <helderijs@gmail.com>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  * ===================================================================
30  */
31 
32 #include <stdio.h>
33 #include "common.h"
34 #include "endianess.h"
35 
36 #define WORDS_IN_BLOCK 16
37 #define WORDS_IN_STATE 8
38 #define BLOCK_SIZE (WORDS_IN_BLOCK*BLAKE2_WORD_SIZE/8)
39 
40 typedef struct {
41         blake2_word h[WORDS_IN_STATE];
42         blake2_word off_counter_low;
43         blake2_word off_counter_high;
44         unsigned buf_occ;
45         uint8_t buf[BLOCK_SIZE];
46 } hash_state;
47 
48 typedef enum { NON_FINAL_BLOCK, FINAL_BLOCK } block_type;
49 
blake2_init(hash_state ** state,const uint8_t * key,size_t key_size,size_t digest_size)50 EXPORT_SYM int blake2_init (hash_state **state,
51                             const uint8_t *key,
52                             size_t key_size,
53                             size_t digest_size)
54 {
55     hash_state *hs;
56     unsigned i;
57 
58     if (NULL == state)
59         return ERR_NULL;
60 
61     if (NULL == key || key_size > MAX_KEY_BYTES)
62         return ERR_KEY_SIZE;
63 
64     if (0 == digest_size || digest_size > MAX_DIGEST_BYTES)
65         return ERR_DIGEST_SIZE;
66 
67     *state = hs = (hash_state*) calloc(1, sizeof(hash_state));
68     if (NULL == hs)
69         return ERR_MEMORY;
70 
71     for (i=0; i<WORDS_IN_STATE; i++) {
72         hs->h[i] = iv[i];
73     }
74     hs->h[0] = (blake2_word)(hs->h[0] ^ 0x01010000 ^ (key_size << 8) ^ digest_size);
75 
76     /** If the key is present, the first block is the key padded with zeroes **/
77     if (key_size>0) {
78         memcpy(hs->buf, key, key_size);
79         hs->buf_occ = BLOCK_SIZE;
80     }
81 
82     return 0;
83 }
84 
blake2_destroy(hash_state * hs)85 EXPORT_SYM int blake2_destroy(hash_state *hs)
86 {
87     free(hs);
88     return 0;
89 }
90 
blake2_copy(const hash_state * src,hash_state * dst)91 EXPORT_SYM int blake2_copy(const hash_state *src, hash_state *dst)
92 {
93     if (NULL == src || NULL == dst) {
94         return ERR_NULL;
95     }
96 
97     *dst = *src;
98     return 0;
99 }
100 
101 #define ROTR(x,n) (((x) >> (n)) ^ ((x) << (BLAKE2_WORD_SIZE - (n))))
102 
103 #define G(v,a,b,c,d,x,y) \
104 { \
105     v[a] = v[a] + v[b] + x; \
106     v[d] = ROTR(v[d] ^ v[a], G_R1); \
107     v[c] = v[c] + v[d]; \
108     v[b] = ROTR(v[b] ^ v[c], G_R2); \
109     v[a] = v[a] + v[b] + y; \
110     v[d] = ROTR(v[d] ^ v[a], G_R3); \
111     v[c] = v[c] + v[d]; \
112     v[b] = ROTR(v[b] ^ v[c], G_R4); \
113 }
114 
blake2b_compress(blake2_word state[8],const blake2_word m[WORDS_IN_BLOCK],blake2_word off_counter_low,blake2_word off_counter_high,block_type bt)115 static void blake2b_compress(blake2_word state[8],
116                              const blake2_word m[WORDS_IN_BLOCK],
117                              blake2_word off_counter_low,
118                              blake2_word off_counter_high,
119                              block_type bt
120                              )
121 {
122     static const uint8_t sigma[12][16] = {
123            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
124            { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
125            { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
126            { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
127            { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
128            { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
129            { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
130            { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
131            { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
132            { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
133            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
134            { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
135     };
136     blake2_word work[WORDS_IN_BLOCK];
137     unsigned i;
138 
139     for (i=0; i<WORDS_IN_STATE; i++) {
140         work[i] = state[i];
141         work[i+WORDS_IN_STATE] = iv[i];
142     }
143 
144     work[12] ^= off_counter_low;
145     work[13] ^= off_counter_high;
146 
147     if (bt == FINAL_BLOCK)
148         work[14] = ~work[14];
149 
150     for (i=0; i<F_ROUNDS; i++) {
151         const uint8_t *s;
152 
153         s = &sigma[i][0];
154         G(work, 0, 4,  8, 12, m[s[ 0]], m[s[ 1]]);
155         G(work, 1, 5,  9, 13, m[s[ 2]], m[s[ 3]]);
156         G(work, 2, 6, 10, 14, m[s[ 4]], m[s[ 5]]);
157         G(work, 3, 7, 11, 15, m[s[ 6]], m[s[ 7]]);
158         G(work, 0, 5, 10, 15, m[s[ 8]], m[s[ 9]]);
159         G(work, 1, 6, 11, 12, m[s[10]], m[s[11]]);
160         G(work, 2, 7,  8, 13, m[s[12]], m[s[13]]);
161         G(work, 3, 4,  9, 14, m[s[14]], m[s[15]]);
162     }
163 
164     for (i=0; i<WORDS_IN_STATE; i++)
165       state[i] ^= work[i] ^ work[i+WORDS_IN_STATE];
166 }
167 
blake2b_process_buffer(hash_state * hs,size_t new_data_added,block_type bt)168 static int blake2b_process_buffer(hash_state *hs,
169                                   size_t new_data_added,
170                                   block_type bt)
171 {
172     blake2_word bufw[WORDS_IN_BLOCK];
173     const uint8_t *buf;
174     unsigned i;
175 
176     buf = hs->buf;
177     for (i=0; i<WORDS_IN_BLOCK; i++) {
178         bufw[i] = LOAD_WORD_LITTLE(buf);
179         buf += sizeof(blake2_word);
180     }
181 
182     hs->off_counter_low = (blake2_word)(hs->off_counter_low + new_data_added);
183     if (hs->off_counter_low < new_data_added) {
184         if (0 == ++hs->off_counter_high)
185             return ERR_MAX_DATA;
186     }
187 
188     blake2b_compress(hs->h,
189                      bufw,
190                      hs->off_counter_low,
191                      hs->off_counter_high,
192                      bt);
193 
194     hs->buf_occ = 0;
195     return 0;
196 }
197 
blake2_update(hash_state * hs,const uint8_t * in,size_t len)198 EXPORT_SYM int blake2_update(hash_state *hs,
199                              const uint8_t *in,
200                              size_t len)
201 {
202     if (NULL == hs)
203         return ERR_NULL;
204 
205     if (len > 0 && NULL == in)
206         return ERR_NULL;
207 
208 
209     while (len > 0) {
210         unsigned tc, left;
211 
212         /** Consume input **/
213         left = (unsigned)(BLOCK_SIZE - hs->buf_occ);
214         tc = (unsigned)MIN(len, left);
215         memcpy(&hs->buf[hs->buf_occ], in, tc);
216         len -= tc;
217         in += tc;
218         hs->buf_occ += tc;
219 
220        /* Flush buffer if full. However, we must leave at least
221         * one byte in the buffer at the end, because we don't
222         * know if we are processing the last block.
223         */
224         if (hs->buf_occ == BLOCK_SIZE && len>0) {
225             int result;
226 
227             result = blake2b_process_buffer(hs, BLOCK_SIZE, NON_FINAL_BLOCK);
228             if (result)
229                 return result;
230         }
231     }
232 
233     return 0;
234 }
235 
blake2_digest(const hash_state * hs,uint8_t digest[MAX_DIGEST_BYTES])236 EXPORT_SYM int blake2_digest(const hash_state *hs,
237                              uint8_t digest[MAX_DIGEST_BYTES])
238 {
239     hash_state temp_hs;
240     unsigned i;
241     int result;
242 
243     if (NULL==hs || NULL==digest)
244         return ERR_NULL;
245 
246     temp_hs = *hs;
247 
248     /** Pad buffer with zeroes, if needed. In the special case
249      *  of no key and no data, we must process an all zero block.
250      */
251     for (i=temp_hs.buf_occ; i<BLOCK_SIZE; i++) {
252         temp_hs.buf[i] = 0;
253     }
254 
255     result = blake2b_process_buffer(&temp_hs,
256                                     temp_hs.buf_occ,
257                                     FINAL_BLOCK);
258     if (result)
259         return result;
260 
261     assert(sizeof temp_hs.h == MAX_DIGEST_BYTES);
262     for (i=0; i<WORDS_IN_STATE; i++) {
263         STORE_WORD_LITTLE(digest, temp_hs.h[i]);
264         digest += sizeof(blake2_word);
265     }
266 
267     return 0;
268 }
269