xref: /freebsd/crypto/libecc/include/libecc/hash/belt-hash.h (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2022 - 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 #include <libecc/lib_ecc_config.h>
12 #ifdef WITH_HASH_BELT_HASH
13 
14 #ifndef __BELT_HASH_H__
15 #define __BELT_HASH_H__
16 
17 #include <libecc/words/words.h>
18 #include <libecc/utils/utils.h>
19 
20 /*
21  * 32-bit integer manipulation macros
22  */
23 #ifndef GET_UINT32_LE
24 #define GET_UINT32_LE(n, b, i)                          \
25 do {                                                    \
26         (n) =     ( ((u32) (b)[(i) + 3]) << 24 )        \
27                 | ( ((u32) (b)[(i) + 2]) << 16 )        \
28                 | ( ((u32) (b)[(i) + 1]) <<  8 )        \
29                 | ( ((u32) (b)[(i)    ])       );       \
30 } while( 0 )
31 #endif
32 
33 #ifndef PUT_UINT32_LE
34 #define PUT_UINT32_LE(n, b, i)                  \
35 do {                                            \
36         (b)[(i) + 3] = (u8) ( (n) >> 24 );      \
37         (b)[(i) + 2] = (u8) ( (n) >> 16 );      \
38         (b)[(i) + 1] = (u8) ( (n) >>  8 );      \
39         (b)[(i)    ] = (u8) ( (n)       );      \
40 } while( 0 )
41 #endif
42 
43 /*
44  * 64-bit integer manipulation macros
45  */
46 #ifndef GET_UINT64_BE
47 #define GET_UINT64_BE(n,b,i)                            \
48 do {                                                    \
49     (n) = ( ((u64) (b)[(i)    ]) << 56 )                \
50         | ( ((u64) (b)[(i) + 1]) << 48 )                \
51         | ( ((u64) (b)[(i) + 2]) << 40 )                \
52         | ( ((u64) (b)[(i) + 3]) << 32 )                \
53         | ( ((u64) (b)[(i) + 4]) << 24 )                \
54         | ( ((u64) (b)[(i) + 5]) << 16 )                \
55         | ( ((u64) (b)[(i) + 6]) <<  8 )                \
56         | ( ((u64) (b)[(i) + 7])            );          \
57 } while( 0 )
58 #endif /* GET_UINT64_BE */
59 
60 #ifndef PUT_UINT64_BE
61 #define PUT_UINT64_BE(n,b,i)            \
62 do {                                    \
63     (b)[(i)    ] = (u8) ( (n) >> 56 );  \
64     (b)[(i) + 1] = (u8) ( (n) >> 48 );  \
65     (b)[(i) + 2] = (u8) ( (n) >> 40 );  \
66     (b)[(i) + 3] = (u8) ( (n) >> 32 );  \
67     (b)[(i) + 4] = (u8) ( (n) >> 24 );  \
68     (b)[(i) + 5] = (u8) ( (n) >> 16 );  \
69     (b)[(i) + 6] = (u8) ( (n) >>  8 );  \
70     (b)[(i) + 7] = (u8) ( (n)       );  \
71 } while( 0 )
72 #endif /* PUT_UINT64_BE */
73 
74 #ifndef GET_UINT64_LE
75 #define GET_UINT64_LE(n,b,i)                            \
76 do {                                                    \
77     (n) = ( ((u64) (b)[(i) + 7]) << 56 )                \
78         | ( ((u64) (b)[(i) + 6]) << 48 )                \
79         | ( ((u64) (b)[(i) + 5]) << 40 )                \
80         | ( ((u64) (b)[(i) + 4]) << 32 )                \
81         | ( ((u64) (b)[(i) + 3]) << 24 )                \
82         | ( ((u64) (b)[(i) + 2]) << 16 )                \
83         | ( ((u64) (b)[(i) + 1]) <<  8 )                \
84         | ( ((u64) (b)[(i)    ])            );          \
85 } while( 0 )
86 #endif /* GET_UINT64_LE */
87 
88 #ifndef PUT_UINT64_LE
89 #define PUT_UINT64_LE(n,b,i)            \
90 do {                                    \
91     (b)[(i) + 7] = (u8) ( (n) >> 56 );  \
92     (b)[(i) + 6] = (u8) ( (n) >> 48 );  \
93     (b)[(i) + 5] = (u8) ( (n) >> 40 );  \
94     (b)[(i) + 4] = (u8) ( (n) >> 32 );  \
95     (b)[(i) + 3] = (u8) ( (n) >> 24 );  \
96     (b)[(i) + 2] = (u8) ( (n) >> 16 );  \
97     (b)[(i) + 1] = (u8) ( (n) >>  8 );  \
98     (b)[(i)    ] = (u8) ( (n)       );  \
99 } while( 0 )
100 #endif /* PUT_UINT64_LE */
101 
102 
103 #define BELT_HASH_BLOCK_SIZE   32
104 #define BELT_HASH_DIGEST_SIZE  32
105 #define BELT_HASH_DIGEST_SIZE_BITS  256
106 
107 /* Compute max hash digest and block sizes */
108 #ifndef MAX_DIGEST_SIZE
109 #define MAX_DIGEST_SIZE 0
110 #endif
111 #if (MAX_DIGEST_SIZE < BELT_HASH_DIGEST_SIZE)
112 #undef MAX_DIGEST_SIZE
113 #define MAX_DIGEST_SIZE BELT_HASH_DIGEST_SIZE
114 #endif
115 
116 #ifndef MAX_DIGEST_SIZE_BITS
117 #define MAX_DIGEST_SIZE_BITS    0
118 #endif
119 #if (MAX_DIGEST_SIZE_BITS < BELT_HASH_DIGEST_SIZE_BITS)
120 #undef MAX_DIGEST_SIZE_BITS
121 #define MAX_DIGEST_SIZE_BITS BELT_HASH_DIGEST_SIZE_BITS
122 #endif
123 
124 #ifndef MAX_BLOCK_SIZE
125 #define MAX_BLOCK_SIZE  0
126 #endif
127 #if (MAX_BLOCK_SIZE < BELT_HASH_BLOCK_SIZE)
128 #undef MAX_BLOCK_SIZE
129 #define MAX_BLOCK_SIZE BELT_HASH_BLOCK_SIZE
130 #endif
131 
132 #define BELT_HASH_HASH_MAGIC ((word_t)(0x3278323b37829187ULL))
133 #define BELT_HASH_HASH_CHECK_INITIALIZED(A, ret, err) \
134         MUST_HAVE((((void *)(A)) != NULL) && ((A)->magic == BELT_HASH_HASH_MAGIC), ret, err)
135 
136 typedef struct {
137 	/* Number of bytes processed */
138 	u64 belt_hash_total;
139 	/* Internal state */
140 	u8 belt_hash_state[BELT_HASH_BLOCK_SIZE];
141 	/* Internal encryption data */
142 	u8 belt_hash_h[BELT_HASH_BLOCK_SIZE];
143 	/* Internal buffer to handle updates in a block */
144 	u8 belt_hash_buffer[BELT_HASH_BLOCK_SIZE];
145 	/* Initialization magic value */
146 	word_t magic;
147 } belt_hash_context;
148 
149 #define BELT_BLOCK_LEN          16 /* The BELT encryption block length */
150 #define BELT_KEY_SCHED_LEN      32 /* The BELT key schedul length */
151 
152 ATTRIBUTE_WARN_UNUSED_RET int belt_init(const u8 *k, u32 k_len, u8 ks[BELT_KEY_SCHED_LEN]);
153 void belt_encrypt(const u8 in[BELT_BLOCK_LEN], u8 out[BELT_BLOCK_LEN], const u8 ks[BELT_KEY_SCHED_LEN]);
154 void belt_decrypt(const u8 in[BELT_BLOCK_LEN], u8 out[BELT_BLOCK_LEN], const u8 ks[BELT_KEY_SCHED_LEN]);
155 
156 ATTRIBUTE_WARN_UNUSED_RET int belt_hash_init(belt_hash_context *ctx);
157 ATTRIBUTE_WARN_UNUSED_RET int belt_hash_update(belt_hash_context *ctx, const u8 *input, u32 ilen);
158 ATTRIBUTE_WARN_UNUSED_RET int belt_hash_final(belt_hash_context *ctx, u8 output[BELT_HASH_DIGEST_SIZE]);
159 ATTRIBUTE_WARN_UNUSED_RET int belt_hash_scattered(const u8 **inputs, const u32 *ilens,
160 		     u8 output[BELT_HASH_DIGEST_SIZE]);
161 ATTRIBUTE_WARN_UNUSED_RET int belt_hash(const u8 *input, u32 ilen, u8 output[BELT_HASH_DIGEST_SIZE]);
162 
163 #endif /* __BELT_HASH_H__ */
164 #endif /* WITH_HASH_BELT_HASH */
165