agievich / bee2
1
/*
2
*******************************************************************************
3
\file belt_cbc.c
4
\brief STB 34.101.31 (belt): CBC 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
Шифрование в режиме CBС
24
*******************************************************************************
25
*/
26
typedef struct
27
{
28
	u32 key[8];			/*< форматированный ключ */
29
	octet block[16];	/*< вспомогательный блок */
30
	octet block2[16];	/*< еще один вспомогательный блок */
31
} belt_cbc_st;
32

33 1
size_t beltCBC_keep()
34
{
35 1
	return sizeof(belt_cbc_st);
36
}
37

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

47 1
void beltCBCStepE(void* buf, size_t count, void* state)
48
{
49 1
	belt_cbc_st* st = (belt_cbc_st*)state;
50 1
	ASSERT(count >= 16);
51 1
	ASSERT(memIsDisjoint2(buf, count, state, beltCBC_keep()));
52
	// цикл по полным блокам
53 1
	while(count >= 16)
54
	{
55 1
		beltBlockXor2(st->block, buf);
56 1
		beltBlockEncr(st->block, st->key);
57 1
		beltBlockCopy(buf, st->block);
58 1
		buf = (octet*)buf + 16;
59 1
		count -= 16;
60
	}
61
	// неполный блок? кража блока
62 1
	if (count)
63
	{
64 1
		memSwap((octet*)buf - 16, buf, count);
65 1
		memXor2((octet*)buf - 16, st->block, count);
66 1
		beltBlockEncr((octet*)buf - 16, st->key);
67
	}
68
}
69

70 1
void beltCBCStepD(void* buf, size_t count, void* state)
71
{
72 1
	belt_cbc_st* st = (belt_cbc_st*)state;
73 1
	ASSERT(count >= 16);
74 1
	ASSERT(memIsDisjoint2(buf, count, state, beltCBC_keep()));
75
	// цикл по полным блокам
76 1
	while(count >= 32 || count == 16)
77
	{
78 1
		beltBlockCopy(st->block2, buf);
79 1
		beltBlockDecr(buf, st->key);
80 1
		beltBlockXor2(buf, st->block);
81 1
		beltBlockCopy(st->block, st->block2);
82 1
		buf = (octet*)buf + 16;
83 1
		count -= 16;
84
	}
85
	// неполный блок? кража блока
86 1
	if (count)
87
	{
88 1
		ASSERT(16 < count && count < 32);
89 1
		beltBlockDecr(buf, st->key);
90 1
		memSwap(buf, (octet*)buf + 16, count - 16);
91 1
		memXor2((octet*)buf + 16, buf, count - 16);
92 1
		beltBlockDecr(buf, st->key);
93 1
		beltBlockXor2(buf, st->block);
94
	}
95
}
96

97 1
err_t beltCBCEncr(void* dest, const void* src, size_t count,
98
	const octet key[], size_t len, const octet iv[16])
99
{
100
	void* state;
101
	// проверить входные данные
102 1
	if (count < 16 ||
103 1
		len != 16 && len != 24 && len != 32 ||
104 1
		!memIsValid(src, count) ||
105 1
		!memIsValid(key, len) ||
106 1
		!memIsValid(iv, 16) ||
107 1
		!memIsValid(dest, count))
108 0
		return ERR_BAD_INPUT;
109
	// создать состояние
110 1
	state = blobCreate(beltCBC_keep());
111 1
	if (state == 0)
112 0
		return ERR_OUTOFMEMORY;
113
	// зашифровать
114 1
	beltCBCStart(state, key, len, iv);
115 1
	memMove(dest, src, count);
116 1
	beltCBCStepE(dest, count, state);
117
	// завершить
118 1
	blobClose(state);
119 1
	return ERR_OK;
120
}
121

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

Read our documentation on viewing source code .

Loading