xref: /freebsd/crypto/libecc/src/examples/hash/gostr34_11_94.h (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2021 - This file is part of libecc project
3  *
4  *  Authors:
5  *      Ryad BENADJILA <ryadbenadjila@gmail.com>
6  *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7  *
8  *  This software is licensed under a dual BSD and GPL v2 license.
9  *  See LICENSE file at the root folder of the project.
10  */
11 #ifndef __GOSTR34_11_94_H__
12 #define __GOSTR34_11_94_H__
13 
14 /* Include libec for useful types and macros */
15 #include <libecc/libec.h>
16 
17 /****************************************************/
18 /*
19  * 32-bit integer manipulation macros
20  */
21 #ifndef GET_UINT32_BE
22 #define GET_UINT32_BE(n, b, i)			  	\
23 do {						    	\
24 	(n) =     ( ((u32) (b)[(i)    ]) << 24 )   	\
25 		| ( ((u32) (b)[(i) + 1]) << 16 )	\
26 		| ( ((u32) (b)[(i) + 2]) <<  8 )	\
27 		| ( ((u32) (b)[(i) + 3])       );       \
28 } while( 0 )
29 #endif
30 #ifndef GET_UINT32_LE
31 #define GET_UINT32_LE(n, b, i)			  	\
32 do {						    	\
33 	(n) =     ( ((u32) (b)[(i) + 3]) << 24 )   	\
34 		| ( ((u32) (b)[(i) + 2]) << 16 )	\
35 		| ( ((u32) (b)[(i) + 1]) <<  8 )	\
36 		| ( ((u32) (b)[(i)    ])       );       \
37 } while( 0 )
38 #endif
39 
40 
41 #ifndef PUT_UINT32_BE
42 #define PUT_UINT32_BE(n, b, i)		  	\
43 do {					    	\
44 	(b)[(i)    ] = (u8) ( (n) >> 24 );      \
45 	(b)[(i) + 1] = (u8) ( (n) >> 16 );      \
46 	(b)[(i) + 2] = (u8) ( (n) >>  8 );      \
47 	(b)[(i) + 3] = (u8) ( (n)       );      \
48 } while( 0 )
49 #endif
50 
51 #ifndef PUT_UINT32_LE
52 #define PUT_UINT32_LE(n, b, i)		  	\
53 do {					    	\
54 	(b)[(i) + 3] = (u8) ( (n) >> 24 );      \
55 	(b)[(i) + 2] = (u8) ( (n) >> 16 );      \
56 	(b)[(i) + 1] = (u8) ( (n) >>  8 );      \
57 	(b)[(i)    ] = (u8) ( (n)       );      \
58 } while( 0 )
59 #endif
60 
61 /*
62  * 64-bit integer manipulation macros
63  */
64 #ifndef GET_UINT64_BE
65 #define GET_UINT64_BE(n,b,i)                            \
66 do {                                                    \
67     (n) = ( ((u64) (b)[(i)    ]) << 56 )                \
68         | ( ((u64) (b)[(i) + 1]) << 48 )                \
69         | ( ((u64) (b)[(i) + 2]) << 40 )                \
70         | ( ((u64) (b)[(i) + 3]) << 32 )                \
71         | ( ((u64) (b)[(i) + 4]) << 24 )                \
72         | ( ((u64) (b)[(i) + 5]) << 16 )                \
73         | ( ((u64) (b)[(i) + 6]) <<  8 )                \
74         | ( ((u64) (b)[(i) + 7])            );          \
75 } while( 0 )
76 #endif /* GET_UINT64_BE */
77 
78 #ifndef GET_UINT64_LE
79 #define GET_UINT64_LE(n,b,i)                            \
80 do {                                                    \
81     (n) = ( ((u64) (b)[(i) + 7]) << 56 )                \
82         | ( ((u64) (b)[(i) + 6]) << 48 )                \
83         | ( ((u64) (b)[(i) + 5]) << 40 )                \
84         | ( ((u64) (b)[(i) + 4]) << 32 )                \
85         | ( ((u64) (b)[(i) + 3]) << 24 )                \
86         | ( ((u64) (b)[(i) + 2]) << 16 )                \
87         | ( ((u64) (b)[(i) + 1]) <<  8 )                \
88         | ( ((u64) (b)[(i)    ])            );          \
89 } while( 0 )
90 #endif /* GET_UINT64_LE */
91 
92 #ifndef PUT_UINT64_BE
93 #define PUT_UINT64_BE(n,b,i)            \
94 do {                                    \
95     (b)[(i)    ] = (u8) ( (n) >> 56 );  \
96     (b)[(i) + 1] = (u8) ( (n) >> 48 );  \
97     (b)[(i) + 2] = (u8) ( (n) >> 40 );  \
98     (b)[(i) + 3] = (u8) ( (n) >> 32 );  \
99     (b)[(i) + 4] = (u8) ( (n) >> 24 );  \
100     (b)[(i) + 5] = (u8) ( (n) >> 16 );  \
101     (b)[(i) + 6] = (u8) ( (n) >>  8 );  \
102     (b)[(i) + 7] = (u8) ( (n)       );  \
103 } while( 0 )
104 #endif /* PUT_UINT64_BE */
105 
106 #ifndef PUT_UINT64_LE
107 #define PUT_UINT64_LE(n,b,i)            \
108 do {                                    \
109     (b)[(i) + 7] = (u8) ( (n) >> 56 );  \
110     (b)[(i) + 6] = (u8) ( (n) >> 48 );  \
111     (b)[(i) + 5] = (u8) ( (n) >> 40 );  \
112     (b)[(i) + 4] = (u8) ( (n) >> 32 );  \
113     (b)[(i) + 3] = (u8) ( (n) >> 24 );  \
114     (b)[(i) + 2] = (u8) ( (n) >> 16 );  \
115     (b)[(i) + 1] = (u8) ( (n) >>  8 );  \
116     (b)[(i)    ] = (u8) ( (n)       );  \
117 } while( 0 )
118 #endif /* PUT_UINT64_LE */
119 
120 #define GOSTR34_11_94_STATE_SIZE   4
121 #define GOSTR34_11_94_BLOCK_SIZE   32
122 #define GOSTR34_11_94_DIGEST_SIZE  32
123 #define GOSTR34_11_94_DIGEST_SIZE_BITS  256
124 
125 #define GOSTR34_11_94_HASH_MAGIC ((word_t)(0x1262734139734143ULL))
126 #define GOSTR34_11_94_HASH_CHECK_INITIALIZED(A, ret, err) \
127 	MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == GOSTR34_11_94_HASH_MAGIC), ret, err)
128 
129 #define ROTL_GOSTR34_11_94(x, n)      ((((u32)(x)) << (n)) | (((u32)(x)) >> (32-(n))))
130 
131 /* All the inner operations */
132 
133 typedef enum {
134 	GOST34_11_94_NORM   = 0,
135 	GOST34_11_94_RFC4357 = 1,
136 } gostr34_11_94_type;
137 
138 typedef struct {
139 	/* "Type" of GOST, changing the SBOX to use */
140 	gostr34_11_94_type gostr34_11_94_t;
141 	/* Number of bytes processed */
142 	u64 gostr34_11_94_total;
143 	/* Internal state: 4 64-bit values */
144 	u64 gostr34_11_94_state[GOSTR34_11_94_STATE_SIZE];
145 	/* Internal buffer to handle updates in a block */
146 	u8 gostr34_11_94_buffer[GOSTR34_11_94_BLOCK_SIZE];
147 	/* The sum */
148 	u64 gostr34_11_94_sum[GOSTR34_11_94_STATE_SIZE];
149 	/* Initialization magic value */
150 	word_t magic;
151 } gostr34_11_94_context;
152 
153 
154 /* Init hash function. Returns 0 on success, -1 on error. */
155 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_init(gostr34_11_94_context *ctx);
156 
157 /* Function to modify the initial IV as it is not imposed by the RFCs */
158 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_set_iv(gostr34_11_94_context *ctx, const u64 iv[GOSTR34_11_94_STATE_SIZE]);
159 
160 /* Function to modify the GOST type (that will dictate the underlying SBOX to use for block encryption) */
161 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_set_type(gostr34_11_94_context *ctx, gostr34_11_94_type type);
162 
163 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_update(gostr34_11_94_context *ctx, const u8 *input, u32 ilen);
164 
165 /* Finalize. Returns 0 on success, -1 on error.*/
166 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_final(gostr34_11_94_context *ctx, u8 output[GOSTR34_11_94_DIGEST_SIZE]);
167 
168 /*
169  * Scattered version performing init/update/finalize on a vector of buffers
170  * 'inputs' with the length of each buffer passed via 'ilens'. The function
171  * loops on pointers in 'inputs' until it finds a NULL pointer. The function
172  * returns 0 on success, -1 on error.
173  */
174 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_scattered(const u8 **inputs, const u32 *ilens,
175 		      u8 output[GOSTR34_11_94_DIGEST_SIZE], gostr34_11_94_type type);
176 
177 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_scattered_norm(const u8 **inputs, const u32 *ilens,
178 		      u8 output[GOSTR34_11_94_DIGEST_SIZE]);
179 
180 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_scattered_rfc4357(const u8 **inputs, const u32 *ilens,
181 		      u8 output[GOSTR34_11_94_DIGEST_SIZE]);
182 
183 /*
184  * Single call version performing init/update/final on given input.
185  * Returns 0 on success, -1 on error.
186  */
187 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94(const u8 *input, u32 ilen, u8 output[GOSTR34_11_94_DIGEST_SIZE], gostr34_11_94_type type);
188 
189 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_norm(const u8 *input, u32 ilen, u8 output[GOSTR34_11_94_DIGEST_SIZE]);
190 
191 ATTRIBUTE_WARN_UNUSED_RET int gostr34_11_94_rfc4357(const u8 *input, u32 ilen, u8 output[GOSTR34_11_94_DIGEST_SIZE]);
192 
193 #endif /* __GOSTR34_11_94_H__ */
194