1
/*
2
*******************************************************************************
3
\file belt_ctr.c
4
\brief STB 34.101.31 (belt): CTR 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/u32.h"
18
#include "bee2/core/util.h"
19
#include "bee2/crypto/belt.h"
20
#include "belt_lcl.h"
21

22
/*
23
*******************************************************************************
24
Шифрование в режиме CTR
25

26
Для ускорения работы счетчик ctr хранится в виде [4]u32. Это позволяет
27
зашифровывать счетчик с помощью функции beltBlockEncr2(), в которой
28
не используется реверс октетов  даже на платформах BIG_ENDIAN.
29
Реверс применяется только перед использованием зашифрованного счетчика
30
в качестве гаммы.
31
*******************************************************************************
32
*/
33

34 1
size_t beltCTR_keep()
35
{
36 1
	return sizeof(belt_ctr_st);
37
}
38

39 1
void beltCTRStart(void* state, const octet key[], size_t len, 
40
	const octet iv[16])
41
{
42 1
	belt_ctr_st* st = (belt_ctr_st*)state;
43 1
	ASSERT(memIsDisjoint2(iv, 16, state, beltCTR_keep()));
44 1
	beltKeyExpand2(st->key, key, len);
45 1
	u32From(st->ctr, iv, 16);
46 1
	beltBlockEncr2(st->ctr, st->key);
47 1
	st->reserved = 0;
48
}
49

50 1
void beltCTRStepE(void* buf, size_t count, void* state)
51
{
52 1
	belt_ctr_st* st = (belt_ctr_st*)state;
53 1
	ASSERT(memIsDisjoint2(buf, count, state, beltCTR_keep()));
54
	// есть резерв гаммы?
55 1
	if (st->reserved)
56
	{
57 1
		if (st->reserved >= count)
58
		{
59 1
			memXor2(buf, st->block + 16 - st->reserved, count);
60 1
			st->reserved -= count;
61 1
			return;
62
		}
63 1
		memXor2(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
		beltBlockIncU32(st->ctr);
72 1
		beltBlockCopy(st->block, st->ctr);
73 1
		beltBlockEncr2((u32*)st->block, st->key);
74
#if (OCTET_ORDER == BIG_ENDIAN)
75
		beltBlockRevU32(st->block);
76
#endif
77 1
		beltBlockXor2(buf, st->block);
78 1
		buf = (octet*)buf + 16;
79 1
		count -= 16;
80
	}
81
	// неполный блок?
82 1
	if (count)
83
	{
84 1
		beltBlockIncU32(st->ctr);
85 1
		beltBlockCopy(st->block, st->ctr);
86 1
		beltBlockEncr2((u32*)st->block, st->key);
87
#if (OCTET_ORDER == BIG_ENDIAN)
88
		beltBlockRevU32(st->block);
89
#endif
90 1
		memXor2(buf, st->block, count);
91 1
		st->reserved = 16 - count;
92
	}
93
}
94

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

Read our documentation on viewing source code .

Loading