1 /*
2 * Copyright (c) 2000, 2002, 2005 X-Way Rights BV
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20 /*!\file blockmode.c
21 * \brief Blockcipher operation modes.
22 * \author Bob Deblier <bob.deblier@telenet.be>
23 * \ingroup BC_m
24 */
25
26 #define BEECRYPT_DLL_EXPORT
27
28 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include "beecrypt/blockmode.h"
33
blockEncryptECB(const blockCipher * bc,blockCipherParam * bp,uint32_t * dst,const uint32_t * src,unsigned int nblocks)34 int blockEncryptECB(const blockCipher* bc, blockCipherParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
35 {
36 register const unsigned int blockwords = bc->blocksize >> 2;
37
38 while (nblocks > 0)
39 {
40 bc->raw.encrypt(bp, dst, src);
41
42 dst += blockwords;
43 src += blockwords;
44
45 nblocks--;
46 }
47
48 return 0;
49 }
50
blockDecryptECB(const blockCipher * bc,blockCipherParam * bp,uint32_t * dst,const uint32_t * src,unsigned int nblocks)51 int blockDecryptECB(const blockCipher* bc, blockCipherParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
52 {
53 register const unsigned int blockwords = bc->blocksize >> 2;
54
55 while (nblocks > 0)
56 {
57 bc->raw.decrypt(bp, dst, src);
58
59 dst += blockwords;
60 src += blockwords;
61
62 nblocks--;
63 }
64
65 return 0;
66 }
67
blockEncryptCBC(const blockCipher * bc,blockCipherParam * bp,uint32_t * dst,const uint32_t * src,unsigned int nblocks)68 int blockEncryptCBC(const blockCipher* bc, blockCipherParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
69 {
70 register const unsigned int blockwords = bc->blocksize >> 2;
71 register uint32_t* fdback = bc->getfb(bp);
72
73 if (nblocks > 0)
74 {
75 register unsigned int i;
76
77 for (i = 0; i < blockwords; i++)
78 dst[i] = src[i] ^ fdback[i];
79
80 bc->raw.encrypt(bp, dst, dst);
81
82 nblocks--;
83
84 while (nblocks > 0)
85 {
86 for (i = 0; i < blockwords; i++)
87 dst[i+blockwords] = src[i+blockwords] ^ dst[i];
88
89 dst += blockwords;
90
91 bc->raw.encrypt(bp, dst, dst);
92
93 src += blockwords;
94
95 nblocks--;
96 }
97
98 for (i = 0; i < blockwords; i++)
99 fdback[i] = dst[i];
100 }
101
102 return 0;
103 }
104
blockDecryptCBC(const blockCipher * bc,blockCipherParam * bp,uint32_t * dst,const uint32_t * src,unsigned int nblocks)105 int blockDecryptCBC(const blockCipher* bc, blockCipherParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
106 {
107 register const unsigned int blockwords = bc->blocksize >> 2;
108 register uint32_t* fdback = bc->getfb(bp);
109 register uint32_t* buf = (uint32_t*) malloc(blockwords * sizeof(uint32_t));
110
111 if (buf)
112 {
113 while (nblocks > 0)
114 {
115 register uint32_t tmp;
116 register unsigned int i;
117
118 bc->raw.decrypt(bp, buf, src);
119
120 for (i = 0; i < blockwords; i++)
121 {
122 tmp = src[i];
123 dst[i] = buf[i] ^ fdback[i];
124 fdback[i] = tmp;
125 }
126
127 dst += blockwords;
128 src += blockwords;
129
130 nblocks--;
131 }
132 free(buf);
133 return 0;
134 }
135
136 return -1;
137 }
138
blockEncryptCTR(const blockCipher * bc,blockCipherParam * bp,uint32_t * dst,const uint32_t * src,unsigned int nblocks)139 int blockEncryptCTR(const blockCipher* bc, blockCipherParam* bp, uint32_t* dst, const uint32_t* src, unsigned int nblocks)
140 {
141 /* host-endian counter is kept in fdback;
142 * swap to big-endian buffer;
143 * encrypt buffer;
144 * src ^ ciphertext -> dst
145 * increment fdback (as mpi) by one inlined;
146 */
147
148 register const unsigned int blockwords = bc->blocksize >> 2;
149 register uint32_t* fdback = bc->getfb(bp);
150 register uint32_t* buf = (uint32_t*) malloc(blockwords * sizeof(uint32_t));
151
152 if (buf)
153 {
154 while (nblocks > 0)
155 {
156 unsigned int i, j;
157
158 #if WORDS_BIGENDIAN
159 bc->raw.encrypt(bp, buf, fdback);
160 #else
161 for (i = 0, j = blockwords-1; i < blockwords; i++, j--)
162 buf[i] = swapu32(fdback[j]);
163 bc->raw.encrypt(bp, buf, buf);
164 #endif
165
166 for (i = 0; i < blockwords; i++)
167 dst[i] = src[i] ^ buf[i];
168
169 dst += blockwords;
170 src += blockwords;
171
172 nblocks--;
173
174 /* increment counter */
175 mpaddw((blockwords >> 1), (mpw*) fdback, 1);
176 }
177 free(buf);
178 return 0;
179 }
180
181 return -1;
182 }
183