agievich / bee2
1
/*
2
*******************************************************************************
3
\file belt_cfb.c
4
\brief STB 34.101.31 (belt): CFB encryption
5
\project bee2 [cryptographic library]
6
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
7
\created 2012.12.18
8
\version 2020.03.24
9
\license This program is released under the GNU General Public License 
10
version 3. See Copyright Notices in bee2/info.h.
11
*******************************************************************************
12
*/
13

14
#include "bee2/core/blob.h"
15
#include "bee2/core/err.h"
16
#include "bee2/core/mem.h"
17
#include "bee2/core/util.h"
18
#include "bee2/crypto/belt.h"
19
#include "belt_lcl.h"
20

21
/*
22
*******************************************************************************
23
Шифрование в режиме CFB
24
*******************************************************************************
25
*/
26
typedef struct
27
{
28
	u32 key[8];			/*< форматированный ключ */
29
	octet block[16];	/*< блок гаммы */
30
	size_t reserved;	/*< резерв октетов гаммы */
31
} belt_cfb_st;
32

33 1
size_t beltCFB_keep()
34
{
35 1
	return sizeof(belt_cfb_st);
36
}
37

38 1
void beltCFBStart(void* state, const octet key[], size_t len, 
39
	const octet iv[16])
40
{
41 1
	belt_cfb_st* st = (belt_cfb_st*)state;
42 1
	ASSERT(memIsDisjoint2(iv, 16, state, beltCFB_keep()));
43 1
	beltKeyExpand2(st->key, key, len);
44 1
	beltBlockCopy(st->block, iv);
45 1
	st->reserved = 0;
46
}
47

48 1
void beltCFBStepE(void* buf, size_t count, void* state)
49
{
50 1
	belt_cfb_st* st = (belt_cfb_st*)state;
51 1
	ASSERT(memIsDisjoint2(buf, count, state, beltCFB_keep()));
52
	// есть резерв гаммы?
53 1
	if (st->reserved)
54
	{
55 1
		if (st->reserved >= count)
56
		{
57 0
			memXor2(st->block + 16 - st->reserved, buf, count);
58 0
			memCopy(buf, st->block + 16 - st->reserved, count);
59 0
			st->reserved -= count;
60 0
			return;
61
		}
62 1
		memXor2(st->block + 16 - st->reserved, buf, st->reserved);
63 1
		memCopy(buf, st->block + 16 - st->reserved, st->reserved);
64 1
		count -= st->reserved;
65 1
		buf = (octet*)buf + st->reserved;
66 1
		st->reserved = 0;
67
	}
68
	// цикл по полным блокам
69 1
	while (count >= 16)
70
	{
71 1
		beltBlockEncr(st->block, st->key);
72 1
		beltBlockXor2(st->block, buf);
73 1
		beltBlockCopy(buf, st->block);
74 1
		buf = (octet*)buf + 16;
75 1
		count -= 16;
76
	}
77
	// неполный блок?
78 1
	if (count)
79
	{
80 1
		beltBlockEncr(st->block, st->key);
81 1
		memXor2(st->block, buf, count);
82 1
		memCopy(buf, st->block, count);
83 1
		st->reserved = 16 - count;
84
	}
85
}
86

87 1
void beltCFBStepD(void* buf, size_t count, void* state)
88
{
89 1
	belt_cfb_st* st = (belt_cfb_st*)state;
90 1
	ASSERT(memIsDisjoint2(buf, count, state, beltCFB_keep()));
91
	// есть резерв гаммы?
92 1
	if (st->reserved)
93
	{
94 1
		if (st->reserved >= count)
95
		{
96 0
			memXor2(buf, st->block + 16 - st->reserved, count);
97 0
			memXor2(st->block + 16 - st->reserved, buf, count);
98 0
			st->reserved -= count;
99 0
			return;
100
		}
101 1
		memXor2(buf, st->block + 16 - st->reserved, st->reserved);
102 1
		memXor2(st->block + 16 - st->reserved, buf, st->reserved);
103 1
		count -= st->reserved;
104 1
		buf = (octet*)buf + st->reserved;
105 1
		st->reserved = 0;
106
	}
107
	// цикл по полным блокам
108 1
	while (count >= 16)
109
	{
110 1
		beltBlockEncr(st->block, st->key);
111 1
		beltBlockXor2(buf, st->block);
112 1
		beltBlockXor2(st->block, buf);
113 1
		buf = (octet*)buf + 16;
114 1
		count -= 16;
115
	}
116
	// неполный блок?
117 1
	if (count)
118
	{
119 1
		beltBlockEncr(st->block, st->key);
120 1
		memXor2(buf, st->block, count);
121 1
		memXor2(st->block, buf, count);
122 1
		st->reserved = 16 - count;
123
	}
124
}
125

126 1
err_t beltCFBEncr(void* dest, const void* src, size_t count,
127
	const octet key[], size_t len, const octet iv[16])
128
{
129
	void* state;
130
	// проверить входные данные
131 1
	if (len != 16 && len != 24 && len != 32 ||
132 1
		!memIsValid(src, count) ||
133 1
		!memIsValid(key, len) ||
134 1
		!memIsValid(iv, 16) ||
135 1
		!memIsValid(dest, count))
136 0
		return ERR_BAD_INPUT;
137
	// создать состояние
138 1
	state = blobCreate(beltCFB_keep());
139 1
	if (state == 0)
140 0
		return ERR_OUTOFMEMORY;
141
	// зашифровать
142 1
	beltCFBStart(state, key, len, iv);
143 1
	memMove(dest, src, count);
144 1
	beltCFBStepE(dest, count, state);
145
	// завершить
146 1
	blobClose(state);
147 1
	return ERR_OK;
148
}
149

150 1
err_t beltCFBDecr(void* dest, const void* src, size_t count,
151
	const octet key[], size_t len, const octet iv[16])
152
{
153
	void* state;
154
	// проверить входные данные
155 1
	if (len != 16 && len != 24 && len != 32 ||
156 1
		!memIsValid(src, count) ||
157 1
		!memIsValid(key, len) ||
158 1
		!memIsValid(iv, 16) ||
159 1
		!memIsValid(dest, count))
160 0
		return ERR_BAD_INPUT;
161
	// создать состояние
162 1
	state = blobCreate(beltCFB_keep());
163 1
	if (state == 0)
164 0
		return ERR_OUTOFMEMORY;
165
	// расшифровать
166 1
	beltCFBStart(state, key, len, iv);
167 1
	memMove(dest, src, count);
168 1
	beltCFBStepD(dest, count, state);
169
	// завершить
170 1
	blobClose(state);
171 1
	return ERR_OK;
172
}
173

Read our documentation on viewing source code .

Loading