Add blake2 support.
[openssl.git] / crypto / blake2 / blake2s.c
1 /*
2  * BLAKE2 reference source code package - reference C implementations
3  *
4  * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.
5  * You may use this under the terms of the CC0, the OpenSSL Licence, or the
6  * Apache Public License 2.0, at your option.  The terms of these licenses can
7  * be found at:
8  *
9  * - OpenSSL license   : https://www.openssl.org/source/license.html
10  * - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
11  * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
12  *
13  * More information about the BLAKE2 hash function can be found at
14  * https://blake2.net.
15  */
16
17 /* crypto/blake2/blake2s.c */
18
19 #include <stdint.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <openssl/crypto.h>
23
24 #include "internal/blake2_locl.h"
25 #include "blake2_impl.h"
26
27 static const uint32_t blake2s_IV[8] =
28 {
29     0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
30     0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
31 };
32
33 static const uint8_t blake2s_sigma[10][16] =
34 {
35     {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
36     { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
37     { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
38     {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
39     {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
40     {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
41     { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
42     { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
43     {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
44     { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
45 };
46
47 /* Some helper functions, not necessarily useful */
48 static inline void blake2s_set_lastblock(BLAKE2S_CTX *S)
49 {
50   S->f[0] = -1;
51 }
52
53 /* Increment the data hashed couter. */
54 static inline void blake2s_increment_counter(BLAKE2S_CTX *S,
55                                              const uint32_t inc)
56 {
57     S->t[0] += inc;
58     S->t[1] += (S->t[0] < inc);
59 }
60
61 /* Initialize the hashing state. */
62 static inline void blake2s_init0(BLAKE2S_CTX *S)
63 {
64     int i;
65
66     memset(S, 0, sizeof(BLAKE2S_CTX));
67     for(i = 0; i < 8; ++i) {
68         S->h[i] = blake2s_IV[i];
69     }
70 }
71
72 /* init2 xors IV with input parameter block */
73 static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)
74 {
75     const uint32_t *p = (const uint32_t *)(P);
76     size_t i;
77
78     /* The param struct is carefully hand packed, and should be 32 bytes on
79      * every platform. */
80     OPENSSL_assert(sizeof(BLAKE2S_PARAM) == 32);
81     blake2s_init0(S);
82     /* IV XOR ParamBlock */
83     for(i = 0; i < 8; ++i) {
84         S->h[i] ^= load32(&p[i]);
85     }
86 }
87
88 /* Initialize the hashing context.  Always returns 1. */
89 int BLAKE2s_Init(BLAKE2S_CTX *c)
90 {
91     BLAKE2S_PARAM P[1];
92
93     P->digest_length = BLAKE2S_DIGEST_LENGTH;
94     P->key_length    = 0;
95     P->fanout        = 1;
96     P->depth         = 1;
97     store32(&P->leaf_length, 0);
98     store48(&P->node_offset, 0);
99     P->node_depth    = 0;
100     P->inner_length  = 0;
101     /* memset(P->reserved, 0, sizeof(P->reserved)); */
102     memset(P->salt,     0, sizeof(P->salt));
103     memset(P->personal, 0, sizeof(P->personal));
104     blake2s_init_param(c, P);
105     return 1;
106 }
107
108 /* Permute the state while xoring in the block of data. */
109 static void blake2s_compress(BLAKE2S_CTX *S,
110                             const uint8_t block[BLAKE2S_BLOCKBYTES])
111 {
112     uint32_t m[16];
113     uint32_t v[16];
114     size_t i;
115
116     for(i = 0; i < 16; ++i) {
117         m[i] = load32(block + i * sizeof(m[i]));
118     }
119
120     for(i = 0; i < 8; ++i) {
121         v[i] = S->h[i];
122     }
123
124     v[ 8] = blake2s_IV[0];
125     v[ 9] = blake2s_IV[1];
126     v[10] = blake2s_IV[2];
127     v[11] = blake2s_IV[3];
128     v[12] = S->t[0] ^ blake2s_IV[4];
129     v[13] = S->t[1] ^ blake2s_IV[5];
130     v[14] = S->f[0] ^ blake2s_IV[6];
131     v[15] = S->f[1] ^ blake2s_IV[7];
132 #define G(r,i,a,b,c,d) \
133     do { \
134         a = a + b + m[blake2s_sigma[r][2*i+0]]; \
135         d = rotr32(d ^ a, 16); \
136         c = c + d; \
137         b = rotr32(b ^ c, 12); \
138         a = a + b + m[blake2s_sigma[r][2*i+1]]; \
139         d = rotr32(d ^ a, 8); \
140         c = c + d; \
141         b = rotr32(b ^ c, 7); \
142     } while(0)
143 #define ROUND(r)  \
144     do { \
145         G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
146         G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
147         G(r,2,v[ 2],v[ 6],v[10],v[14]); \
148         G(r,3,v[ 3],v[ 7],v[11],v[15]); \
149         G(r,4,v[ 0],v[ 5],v[10],v[15]); \
150         G(r,5,v[ 1],v[ 6],v[11],v[12]); \
151         G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
152         G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
153     } while(0)
154     ROUND(0);
155     ROUND(1);
156     ROUND(2);
157     ROUND(3);
158     ROUND(4);
159     ROUND(5);
160     ROUND(6);
161     ROUND(7);
162     ROUND(8);
163     ROUND(9);
164
165     for(i = 0; i < 8; ++i) {
166         S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
167     }
168
169 #undef G
170 #undef ROUND
171 }
172
173 /* Absorb the input data into the hash state.  Always returns 1. */
174 int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen)
175 {
176     const uint8_t *in = data;
177     size_t fill;
178
179     while(datalen > 0) {
180         fill = sizeof(c->buf) - c->buflen;
181         /* Must be >, not >=, so that last block can be hashed differently */
182         if(datalen > fill) {
183             memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
184             blake2s_increment_counter(c, BLAKE2S_BLOCKBYTES);
185             blake2s_compress(c, c->buf); /* Compress */
186             c->buflen = 0;
187             in += fill;
188             datalen -= fill;
189         } else { /* datalen <= fill */
190             memcpy(c->buf + c->buflen, in, datalen);
191             c->buflen += datalen; /* Be lazy, do not compress */
192             return 1;
193         }
194     }
195
196     return 1;
197 }
198
199 /*
200  * Finalize the hash state in a way that avoids length extension attacks.
201  * Always returns 1.
202  */
203 int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c)
204 {
205     int i;
206
207     blake2s_increment_counter(c, (uint32_t)c->buflen);
208     blake2s_set_lastblock(c);
209     /* Padding */
210     memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
211     blake2s_compress(c, c->buf);
212
213     /* Output full hash to temp buffer */
214     for(i = 0; i < 8; ++i) {
215         store32(md + sizeof(c->h[i]) * i, c->h[i]);
216     }
217
218     OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));
219     return 1;
220 }