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