/ external / libecc / src / examples / hash / gostr34_11_94.h
gostr34_11_94.h
  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__ */